Description
Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.
For example,
"A man, a plan, a canal: Panama" is a palindrome.
"race a car" is not a palindrome.
Note:
Have you consider that the string might be empty? This is a good question to ask during an interview.
For the purpose of this problem, we define empty string as valid palindrome.
題目分析
本題中要求對(duì)于一給定字符串寒锚,判斷其是否屬于回文(palindrome),所謂回文是指順讀和倒讀都一樣的詞語(yǔ)雳锋。題目中要求判斷的內(nèi)容僅包含數(shù)字和字母兩種字符,標(biāo)點(diǎn)符號(hào)不屬于判斷內(nèi)容蜘拉。如
example1:
strs1="A man, a plan, a canal: Panama"
output:true
example2 :
strs2="race a car"
output:false
字符串strs1中除標(biāo)點(diǎn)符號(hào)外的字符順讀與倒讀均相同(忽略字幕大小寫)芒划,er字符串strs2中順讀與倒讀不一致,故輸出false贼穆。
解題思路
所謂回文是指順讀和倒讀均相同的字符串哼御,因此屬于回文的字符串必定左右對(duì)稱坯临。我們只需要判定所給的字符串是否左右對(duì)稱即可解決問(wèn)題。
由于恋昼,所給字符串中可能包含標(biāo)點(diǎn)符號(hào)看靠,而標(biāo)點(diǎn)符號(hào)不在判斷之列,因此第一步需要將字符串中的標(biāo)點(diǎn)符號(hào)去掉液肌,只留下字母和數(shù)字衷笋;由于所給字符串中的字母是大小寫混合存在,第二步矩屁,將字符串中的字母化為同一,或全為大寫爵赵,或全小寫吝秕;第三步,判斷字符是否左右對(duì)稱空幻,若發(fā)現(xiàn)一個(gè)位置不對(duì)稱烁峭,則輸出false,若全部對(duì)稱,輸出true约郁。
特殊情況:
(1)空字符串(“”)。對(duì)于空字符串鬓梅,認(rèn)為其屬于回文,輸出true绽快。
(2)字符串中僅含有一個(gè)字符。單個(gè)字符與其本身對(duì)稱坊罢,也屬于回文续担,因此輸出true。
C語(yǔ)言代碼
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
bool isPalindrome(char* strs) {
int len=strlen(strs);
bool flag=false;
int i=0,j=0;
if (len==0 || len==1) //長(zhǎng)度為1或0
return true;
char string[len];
while(strs[i]!='\0')
{
if('A'<=strs[i] && strs[i]<='Z') //大寫變?yōu)樾?
{
string[j]=strs[i]+'a'-'A';
j=j+1;
}
if(('a'<=strs[i] && strs[i]<='z') ||
('0'<=strs[i] && strs[i]<='9') ) //小寫字母與數(shù)字不做變換
{
string[j]=strs[i];
j++;
}
i++;
}
string[j]='\0'; //末尾加‘\0’,提高運(yùn)行速度
for(i=0;i<j/2;i++) //判斷是否左右對(duì)稱物遇,最多只需判斷其長(zhǎng)度的一般
{
if(string[i]!=string[j-i-1]) //找到一個(gè)不一致,說(shuō)明不對(duì)稱询兴,結(jié)束
break;
}
if(i==j/2) //所有對(duì)應(yīng)位都相同,即說(shuō)明左右對(duì)稱
flag=true;
return flag;
}
int main()
{
char *strs="ab";
bool flag;
flag=isPalindrome(strs);
printf("%d",flag);
return 0;
}
對(duì)于字符串航夺,C語(yǔ)言中是以數(shù)組(字符數(shù)組)的形式存放蕉朵,數(shù)組元素的類型為char,其長(zhǎng)度為1個(gè)字節(jié)阳掐。因而字符指針指向存放該字符串的數(shù)組地址。字符指針的字面量表示存放該字符串的數(shù)組的首個(gè)元素的地址缭保。對(duì)于指針變量進(jìn)行加減操作,相當(dāng)于獎(jiǎng)賞這個(gè)整數(shù)和指針數(shù)據(jù)類型對(duì)應(yīng)字節(jié)數(shù)的乘積艺骂。
對(duì)于字符指針,由于其指向字符串的首地址钳恕,其對(duì)應(yīng)的數(shù)據(jù)類型為char,數(shù)據(jù)長(zhǎng)度為1厘肮,因此指針字符加一,相當(dāng)于地址加一睦番,因此可以通過(guò)指針加一來(lái)訪問(wèn)字符串的單個(gè)字符耍属。本題也可以通過(guò)指針加一的方式來(lái)訪問(wèn)字符串的各個(gè)字符巩检。
bool isPalindrome(char* strs) {
int len=strlen(strs);
bool flag=false;
int i=0,j=0;
if (len==0 || len==1) //長(zhǎng)度為1或0
return true;
char string[len];
while(*strs!='\0') //strs代表首地址,*解引用就表示單個(gè)字符
{
if('A'<=*strs && *strs<='Z') //大寫變?yōu)樾?
{
string[j]=*strs+'a'-'A';
j=j+1;
}
if(('a'<=*strs && *strs<='z') ||
('0'<=*strs && *strs<='9') ) //小寫字母與數(shù)字不做變換
{
string[j]=*strs;
j++;
}
strs++;
}
string[j]='\0'; //末尾加‘\0’,提高運(yùn)行速度
for(i=0;i<j/2;i++) //判斷是否左右對(duì)稱领舰,最多只需判斷其長(zhǎng)度的一般
{
if(string[i]!=string[j-i-1]) //找到一個(gè)不一致厦瓢,說(shuō)明不對(duì)稱提揍,結(jié)束
break;
}
if(i==j/2) //所有對(duì)應(yīng)位都相同煮仇,即說(shuō)明左右對(duì)稱
flag=true;
return flag;
}
參考文獻(xiàn)
[1] https://leetcode.com/submissions/detail/110747419/
[2] 《深入理解C指針》