数组操作——滑动窗口
所谓滑动窗口,就是不断地调整子数组地起始位置和终止位置,从而得出想要的结果。
- 例题:今日leetCode每日一题 :1984. 学生分数的最小差值
给你一个 下标从 0 开始的整数数组 nums ,其中 nums[i] 表示第 i 名学生的分数。另给你一个整数 k 。
从数组中选出任意 k 名学生的分数,使这 k 个分数间最高分和最低分的差值达到最小化 。
返回可能的最小差值 。
//排序+滑动窗口
public int minimumDifference(int[] nums, int k) {
int n = nums.length;
Arrays.sort(nums);
int ans = Integer.MAX_VALUE;
int i = 0;//起始位置
for (int j = 0; j < n; j++) {//结束位置
while (j - i + 1 == k) {
ans = Math.min(ans, nums[j] - nums[i]);
i++;
}
}
return ans == Integer.MAX_VALUE ? 0 : ans;
}
- 例题:leetCode 209. 长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
/**
* 窗口内部的元素:保持窗口内数值总和大于或等于target,且为长度最小的连续数组
移动窗口的起始位置:如果当前窗口内数值的总和大于target,则窗口前移(窗口缩小)
移动窗口的结束位置:窗口结束的位置就是j,遍历完数组即结束。
*/
public int minSubArrayLen(int target, int[] nums) {
int res = Integer.MAX_VALUE;
int sum = 0; //窗口内的数值之和
int subLength = 0; //子数组长度
int i = 0; //起始位置
for (int j = 0; j < nums.length; j++) { //结束位置
sum += nums[j];
while (sum >= target) {
subLength = j - i + 1; //取子数组的长度
res = res < subLength ? res : subLength;
//滑动窗口的精髓,不断变更i(子数组的起始位置)
sum -= nums[i++];
}
}
return res == Integer.MAX_VALUE ? 0 : res;
}
- 力扣LC219,LC438,LC220等滑动窗口的题目可供练习。