刷题--双指针(1)

双指针的使用征兆 --- 时间复杂度是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;
    }
}

 

你可能感兴趣的:(刷题--双指针(1))