数组操作——滑动窗口

所谓滑动窗口,就是不断地调整子数组地起始位置和终止位置,从而得出想要的结果。

  • 例题:今日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等滑动窗口的题目可供练习。