6190. 找到所有好下标

112 阅读1分钟

难度:中等

解题思路:预处理

题目描述

给你一个大小为 n 下标从 0 开始的整数数组 nums 和一个正整数 k 。

对于 k <= i < n - k 之间的一个下标 i ,如果它满足以下条件,我们就称它为一个  下标:

  • 下标 i 之前 的 k 个元素是 非递增的 。
  • 下标 i 之后 的 k 个元素是 非递减的 。

升序 返回所有好下标。

示例

输入:nums = [2,1,1,1,3,4,1], k = 2
输出:[2,3]
解释:数组中有两个好下标:
- 下标 2 。子数组 [2,1] 是非递增的,子数组 [1,3] 是非递减的。
- 下标 3 。子数组 [1,1] 是非递增的,子数组 [3,4] 是非递减的。
注意,下标 4 不是好下标,因为 [4,1] 不是非递减的。

解题思路

解题思路像是矩阵中全一长方形一样,我们可以借此思路,预处理每个点left(左侧非递增最长长度)、right(右侧非递减最长长度)

                                         [2,1,1,1,3,4,1]
                   左侧非递增最长长度left:[1,2,3,4,1,2,3]
                  右侧非递减最长长度right:[1,5,4,3,2,1,1]

向如上预处理,单次循环下标index,

  • left[index-1]表示index左侧非递增最长长度,如果left[index-1]>=k,则左侧是符合要求的
  • right[index+1]表示index右侧非递减最长长度,如果right[index+1]>=k,则右侧是符合要求的
  • 当上述两个条件均满足时,则index为好下标
class Solution {
public:
    vector<int> goodIndices(vector<int>& nums, int k) {
        int n=nums.size();
        vector<int>ans;
        vector<int>left(n,1);//左侧非递增最大长度(包括自己)
        vector<int>right(n,1);//右侧非递减最大长度(包括自己)
        for(int i=1;i<n;i++){
            if(nums[i]<=nums[i-1])left[i]+=left[i-1];
        }
        for(int i=n-2;i>=0;i--){
            if(nums[i]<=nums[i+1])right[i]+=right[i+1];
        }
        for(int i=k;i<n-k;i++){
            if(left[i-1]>=k&&right[i+1]>=k)ans.push_back(i);
        }
        return ans;
    }
};

复杂度分析:

时间复杂度O(n)空间复杂度O(n)