验证回文串(125. 验证回文串)
题目:
思路:
【1】这题一看率先会想到的就是双指针,通过头尾两个指针指向,进行比对,遇到空格以及特殊字符要跳过,然后判断,如图:
【2】另外本身我们还可以使用默认的函数方法来处理,如,用正则匹配清除非字母数字字符,然后转成小写,再反转,再匹配。
代码展示:
双指针的两种写法:
第一种,在循环里面拿到字符转成小写后进行比对,如果成功则两者都要移动一位:
public boolean isPalindrome(String s) { if (s.length() == 0) return true; int left = 0, right = s.length() - 1; while (left < right) { //因为题中说了,只考虑字母和数字,所以不是字母和数字的先过滤掉 while (left < right && !Character.isLetterOrDigit(s.charAt(left))) left++; while (left < right && !Character.isLetterOrDigit(s.charAt(right))) right--; //然后把两个字符变为小写,在判断是否一样,如果不一样,直接返回false if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) return false; left++; right--; } return true; }
第二种,其实和第一种差不多,但是是优先先将整个字符串转成小写:
public boolean isPalindrome(String s) { if (s == null || s.length() == 0) return true; s = s.toLowerCase(); for (int i = 0, j = s.length() - 1; i < j; i++, j--) { while (i < j && !Character.isLetterOrDigit(s.charAt(i))) i++; while (i < j && !Character.isLetterOrDigit(s.charAt(j))) j--; if (s.charAt(i) != s.charAt(j)) return false; } return true; }
此外,如果不做循坏的话还可以用递归的方式来替代循环:
public boolean isPalindrome(String s) { return isPalindromeHelper(s, 0, s.length() - 1); } public boolean isPalindromeHelper(String s, int left, int right) { if (left >= right) return true; while (left < right && !Character.isLetterOrDigit(s.charAt(left))) left++; while (left < right && !Character.isLetterOrDigit(s.charAt(right))) right--; return Character.toLowerCase(s.charAt(left)) == Character.toLowerCase(s.charAt(right)) && isPalindromeHelper(s, ++left, --right); }
怎么使用默认函数进行处理:
public boolean isPalindrome(String s) { String actual = s.replaceAll("[^A-Za-z0-9]", "").toLowerCase(); String rev = new StringBuffer(actual).reverse().toString(); return actual.equals(rev); }