找到所有好下标
难度:
标签:
题目描述
代码结果
运行时间: 87 ms, 内存: 27.7 MB
/*
* 思路:
* 1. 使用两个数组 left 和 right 分别记录每个位置之前和之后的非递增和非递减长度。
* 2. 遍历数组,根据条件找到所有的好下标。
*/
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
public class GoodIndicesStream {
public List<Integer> goodIndices(int[] nums, int k) {
int n = nums.length;
int[] left = new int[n];
int[] right = new int[n];
List<Integer> result = new ArrayList<>();
// 初始化left数组
IntStream.range(0, n).forEach(i -> {
if (i == 0 || nums[i] <= nums[i - 1]) {
left[i] = (i == 0) ? 1 : left[i - 1] + 1;
} else {
left[i] = 1;
}
});
// 初始化right数组
IntStream.iterate(n - 1, i -> i >= 0, i -> i - 1).forEach(i -> {
if (i == n - 1 || nums[i] <= nums[i + 1]) {
right[i] = (i == n - 1) ? 1 : right[i + 1] + 1;
} else {
right[i] = 1;
}
});
// 查找好下标
IntStream.range(k, n - k).filter(i -> left[i - 1] >= k && right[i + 1] >= k).forEach(result::add);
return result;
}
public static void main(String[] args) {
GoodIndicesStream solution = new GoodIndicesStream();
int[] nums = {2, 1, 1, 1, 3, 4, 1};
int k = 2;
System.out.println(solution.goodIndices(nums, k)); // 输出: [2, 3]
}
}
解释
方法:
解题思路主要是通过一次遍历来检查每一个可能的好下标。首先,初始化三个指针:left、right 和 cur。left 和 right 分别代表检查非递增和非递减子数组的起始位置。cur 用于计数连续满足条件的元素个数。遍历过程中,如果当前的元素满足非递增和非递减的条件,cur 递增并移动 left 和 right。当 cur 达到 k 时,说明找到了一个好下标并将其加入结果列表。如果条件被打破,cur 重置为 1。这种方法避免了多次重复检查子数组的情况。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
在题解中提到的`滑动窗口检查每个可能的好下标`策略如何确保不会错过任何一个好下标?
▷🦆
题解中提到,如果连续满足条件的元素个数达到k,记录为好下标。那么,如果在达到k之后的下一次迭代中条件不再满足,是如何处理的?
▷🦆
题解中没有详细解释如何处理`cur`在不满足条件时的重置逻辑,能否详细说明这一部分的处理逻辑?
▷🦆
题解说明中提到,当`right`指针到达数组末尾前,循环就会停止。这是否意味着数组的最后几个元素不会被完全检查?
▷