题意:
解题思路:
思路:
(线性扫描) O(n)
1. 用两个指针分别从前后开始,往中间扫描。
2. 每次迭代两个指针分别向中间靠近一步,靠近的过程中忽略除了字母和数字的其他字符。
3. 然后判断两个指针所指的字符是否相等,如果不相等,说明不是回文串。
4.当两个指针相遇时,说明原字符串是回文串。
时间复杂度分析:每个字符仅会被扫描一次,所以时间复杂度是 O(n)。
PHP代码实现:
class Solution {
function isAlphanumeric($s) {
return ($s >= 'a' && $s <= 'z') || ($s >= 'A' && $s <= 'Z')
|| ($s >= '0' && $s <= '9');
}
function isEqualIgnoreCase($a, $b) {
if ($a >= 'A' && $a <= 'Z') $a = strtolower($a);
if ($b >= 'A' && $b <= 'Z') $b = strtolower($b);
return $a == $b;
}
function isPalindrome1($s) {
if ($s == null || strlen($s) == 0) return true;
$i = 0; $j = strlen($s) - 1;
for (; $i < $j; ++$i, --$j) {
//不是字母或者数字,i < j:防止移动到j后面
while ($i < $j && !$this->isAlphanumeric($s[$i])) ++$i;
while ($i < $j && !$this->isAlphanumeric($s[$j])) --$j;
if ($i < $j && strtolower($s[$i]) != strtolower($s[$j])) return false;
}
return true;
}
/**
* @param String $s
* @return Boolean
*/
function isPalindrome($s) {
return $this->isPalindrome1($s);
if (empty($s)) return true;
$str = $rStr = '';
$count = strlen($s);
$l = 0;
$r = $count - 1;
while ($l < $r) {
$lLetter = $this->isLetter($s[$l]);
$rLetter = $this->isLetter($s[$r]);
if ($lLetter === false) {
$l++;
continue;
}
if ($rLetter === false) {
$r--;
continue;
}
if ($lLetter != $rLetter) {
return false;
}
$l++;$r--;
}
return true;
}
function isLetter($str) {
if ($str >= 'a' && $str <= 'z') {
return $str;
} else if ($str >= 'A' && $str <= 'Z') {
return chr(ord($str) + 32);
} else if (in_array($str,['0','1','2','3','4','5','6','7','8','9'])) {
return $str;
}
return false;
}
}
GO代码实现:
func isPalindrome(s string) bool {
if s == "" {
return true
}
s = strings.ToLower(s)
n := len(s)
i, j := 0, n-1
for i < j {
if !isValidChar(s[i]) {
i++
continue
}
if !isValidChar(s[j]) {
j--
continue
}
if s[i] != s[j] {
return false
}
i++
j--
}
return true
}
func isValidChar(char byte) bool {
return (char >= 'A' && char <= 'Z') ||
(char >= 'a' && char <= 'z') ||
(char >= '0' && char <= '9')
}