双指针的使用征兆 --- 时间复杂度是O(n),可能会用双指针。尤其是要求时间复杂度从O(n^2)降到O(n)。
相向双指针:两个指针一头一尾
reverse类:1 三步翻转法
2 验证回文串
例 lintcode 415. Valid Palindrome https://www.lintcode.com/problem/valid-palindrome/description
注意的点 :java String 的 .charAt(), 对于单个字符判断是否是字母:Character.isLetter(), 是否是数字或者字母 Character.isLetterOrDigit(), 同样也有 Character.isDigit()
public boolean isPalindrome(String s) { int i = 0, j = s.length() - 1; while(i < j){ while(i < j && !Character.isLetterOrDigit(s.charAt(i))) i++; while(i < j && !Character.isLetterOrDigit(s.charAt(j))) j--; if(Character.toLowerCase(s.charAt(i)) != Character.toLowerCase(s.charAt(j))) return false; i++; j--; } return true; } }
这道题的重点在于follow up 证明一个字符串在删去一个字符之后能否构成回文。首先找到不一样的对称位置的字符,然后分别跳过他们继续进行双指针验证。总共调用了三次双指针的函数。因为java只能有一个返回值,而我们需要用到第一次同向双指针的两个位置,所以如果想只调用双指针函数的话还得新建一个class。
例 lintcode 891. Valid Palindrome II https://www.lintcode.com/problem/valid-palindrome-ii/description
class reType{ int left; int right; public reType(int left, int right){ this.left = left; this.right = right; } } public boolean validPalindrome(String s) { if(s == null || s.length() == 0) return true; reType index = isPalin(s, 0, s.length() - 1); if(index.left >= index.right)return true; reType leftRemove = isPalin(s, index.left + 1, index.right); reType rightRemove = isPalin(s, index.left, index.right - 1); return leftRemove.left >= leftRemove.right || rightRemove.left >= rightRemove.right; } public reType isPalin(String s, int start, int end){ while(start < end){ if(s.charAt(start) == s.charAt(end)){ start ++; end --; }else{ break; } } return new reType(start, end); } }
九章的答案没有新建class,也就会产生代码重复的问题。
class Solution { public boolean validPalindrome(String s) { int left = 0, right = s.length() - 1; while (left < right) { if (s.charAt(left) != s.charAt(right)) { break; } left++; right--; } if (left >= right) { return true; } return isSubPalindrome(s, left + 1, right) || isSubPalindrome(s, left, right - 1); } private boolean isSubPalindrome(String s, int left, int right) { while (left < right) { if (s.charAt(left) != s.charAt(right)) { return false; } left++; right--; } return true; } }