找出最长等值子数组

22 阅读1分钟

给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 如果子数组中所有元素都相等,则认为子数组是一个 等值子数组 。注意,空数组是 等值子数组 。 从 nums 中删除最多 k 个元素后,返回可能的最长等值子数组的长度。 子数组 是数组中一个连续且可能为空的元素序列。

输入:nums = [1,3,2,3,1,3], k = 3 输出:3

  • 记录所有等值子数组的每个元素在nums中对应的位置于position表
  • 遍历position表,pos[right]-pos[left]的应该大于或等于right-left,大于的值应该小于或等于k,k为能更改的次数嘛,不同的我就改
  • pos[right]-pos[left]-(right-left)>k时移动pos中的left
class Solution {
public:
    int longestEqualSubarray(vector<int>& nums, int k) {
        int n=nums.size();int res=1;
        vector<vector<int>> position(n+1);
        for(int i=0;i<n;i++){
            int x=nums[i];
            position[x].push_back(i);
        }
        for(auto &pos:position){
            int left=0;
            for(int right=0;right<pos.size();right++){
                while(pos[right]-pos[left]-(right-left)>k){
                    left++;
                }
                res=res<right-left+1?right-left+1:res;
            }
        }
        return res;
    }
};

滑动窗口:定长

class Solution {

public:

    int longestEqualSubarray(vector<int>& nums, int k) {

        int n=nums.size();int res=1;int sum=0;

            for(int i=0;i<n;i++){//右边扩展
                sum+=nums[i];
                if(i<k-1) continue;//到达定长
                sum-=nums[i-k+1];//左边收缩
                res=res<sum?sum:res;//更改状态
            }
        }
        return res;
    }

};

滑动窗口:不定长

class Solution {

public:

    int longestEqualSubarray(vector<int>& nums, int k) {

        int n=nums.size();int res=1;

            for(int right=0;right<pos.size();right++){
            
                while(限制条件,与left有关){
                    left++;
                }
                res=res<right-left+1?right-left+1:res;//求出极值
            }
        }
        return res;

    }

};