lintcode 568 · Three chances [double pointer vip medium]

topic

https://www.lintcode.com/problem/568

给出一个整数数组,所有的元素都在 [10,10] 之间。
你有三次机会将数组中的一个数替换成任意数。
请求出可能的最长相等子段数列的长度。



数组的长度为 n, 1≤n≤10 ^5
第一个样例中,可以将数组变成 
[0,0,0,0,0,3] 或者 
[0,3,3,3,3,3],结果都是 5

样例
输入:
[0,3,1,0,6,3]
输出:
5
输入:
[1,2]
输出:
2

Ideas

双指针即可:子串问题,通常考虑以某个位置为开头怎么样,某个位置结尾怎么样。
针对本题,我们考虑0...i  假设第i位不变,往后找到三个不同的位置,如果到了
位置j,j>i   时有4个数不等于i位置的数,那么就计算j-i之间的距离,取最大。
注意:整个数组的元素是一样的情况的,或者整个数组除了只有1个,2个,或者3个位置
的数不一样之外,其他位置一样的情况

Answer

public class Solution {
    
    
    /**
     * @param nums: an integer array.
     * @return: return the possible longest length of the subarray that elements are the same.
     */
    public int threeChances(int[] nums) {
    
    
         int max = Integer.MIN_VALUE;
        int n = nums.length;
        if(n<=4) return n;
        int L=0,R=1,cnt=0;   //cnt 改变数超过3个,内层停止
        for (; L<n-3 ; L++) {
    
    
            int cur = nums[L]; //当前数不变动,让不一样的变成当前的一样
           cnt = 0;
            for (R=L+1; R< n; R++) {
    
    
                int next = nums[R];
                if(next!=cur)
                    cnt++;

                
                if(cnt ==4){
    
    
                    max = Math.max(R-L,max);
                    break;
                }
            }

            //R走到最后了,cnt小等于3个,那么可以结束循环了
           if(cnt <=3){
    
     //cnt:0数组中所有元素一样的情况以及其他情况
               max = Math.max(max,R-L);
               break;
           }
        }

        return max;
    }
}

local test code

public class LC568 {
    
    

    public static int threeChances(int[] nums) {
    
    
        int max = Integer.MIN_VALUE;
        int n = nums.length;
        if(n<=4) return n;
        int L=0,R=1,cnt=0;   //cnt 改变数超过3个,内层停止
        for (; L<n-3 ; L++) {
    
    
            int cur = nums[L]; //当前数不变动,让不一样的变成当前的一样
           cnt = 0;
            for (R=L+1; R< n; R++) {
    
    
                int next = nums[R];
                if(next!=cur)
                    cnt++;


                if(cnt ==4){
    
    
                    max = Math.max(R-L,max);
                    break;
                }
            }

            //R走到最后了,cnt小等于3个,那么可以结束循环了
           if(cnt <=3){
    
     //cnt:0数组中所有元素一样的情况以及其他情况
               max = Math.max(max,R-L);
               break;
           }
        }

        return max;
    }

    public static void main(String[] args) {
    
    
        System.out.println(threeChances(new int[]{
    
    0,3,1,0,6,3})); //5
        System.out.println(threeChances(new int[]{
    
    1,2})); //2
        System.out.println(threeChances(new int[]{
    
    3,-4,-1,-5,4,6,6,7,-10,-5})); //5
        System.out.println(threeChances(new int[]{
    
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0})); //68
    }
}

Guess you like

Origin blog.csdn.net/weixin_37991016/article/details/132819540