初级算法

mac2026-08-26  10

这是第二道题。

题目描述

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

说明:本题中,我们将空字符串定义为有效的回文串。

示例 1:

输入: “A man, a plan, a canal: Panama” 输出: true

示例 2:

输入: “race a car” 输出: false

解题思路

思路一:

从题目中可以知道只需要考虑字母和数字且不区分大小写,所以直接比较原字符串比较复杂,先转换成只包含字母和数字,且全部转换成小写字母,然后进行比较就可以了。 步骤如下:

字符串转换成小写字母和数字;比较字符串是否对称。
思路二:

直接两个索引分别从头、尾开始,分别找到第一个是字母或者数字的字符,开始比较,循环遍历到索引相遇。 这样写感觉比较复杂,但是省内存。

我用的第一种思路。

代码

bool isPalindrome(char * s) { char acTmp[1000000]; /* 这里偷懒没有或取s长度,申请内存;好吧,其实是我忘了 */ bool bRet = true; int iStrLen = 0; int iLoop = 0; int i; char cTrans = 'A' - 'a'; while (0 != *s) { if ((('a' <= *s) && (*s <= 'z')) || (('0' <= *s) && (*s <= '9'))) { acTmp[iStrLen++] = *s; } else if (('A' <= *s) && (*s <= 'Z')) { acTmp[iStrLen++] = *s - cTrans; } s++; } iLoop = iStrLen / 2; --iStrLen; for (i = 0; i < iLoop; i++) { if (acTmp[i] != acTmp[iStrLen - i]) /* 注释1 */ { bRet = false; break; } } return bRet; }

易错点: 说是易错点,其实是我出错的地方。

我忘记了数字也要判断;注释1 的地方又又又越界了。

运行结果

看答案

bool isPalindrome(char * s){ if (s == NULL) { return true; } int cnt = 0; for (int i = 0; s[i] != '\0'; i++) { if (s[i] >= 'A' && s[i] <= 'Z'){ cnt++; } else if (s[i] >= 'a' && s[i] <= 'z') { cnt++; } else if (s[i] >= '0' && s[i] <= '9') { cnt++; } } char *p = (char *)malloc(cnt*sizeof(char)); int tmp = 0; for (int i = 0; s[i] != '\0'; i++) { if (s[i] >= 'A' && s[i] <= 'Z'){ p[tmp++] = s[i] + 'a' - 'A'; } else if (s[i] >= 'a' && s[i] <= 'z') { p[tmp++] = s[i] ; } else if (s[i] >= '0' && s[i] <= '9') { p[tmp++] = s[i] ; } } for (int i = 0, j = cnt - 1; i < cnt;) { if(p[i++] != p[j--]) { return false; } } return true; }

好像也差不多。。为啥这个0ms我的8ms。。。

总结

内存越界的问题还是很容易犯的。

最新回复(0)