java 滑动窗口
![](https://img2022.cnblogs.com/blog/1437100/202208/1437100-20220813211053908-614532702.png)
数组A中每间隔Y-1个的连续X个数的最小和
public static int solution(int[] A, int X, int Y) { int n = A.length; int l = 0, r = (X - 1) * Y; int minn = 9999999; while (r < n) { int ans = 0; int i = 0; for (i = 0; i < X; i++) { //会有很多重复运算 System.out.print(A[l + i * Y]); ans += A[l + i * Y]; } System.out.println(); if (i == X && ans < minn) minn = ans; l++; r++; } return minn; }
优化 O(n)
public static int solution(int [] A, int X, int Y) { // write your code in Java 8 (Java SE 8) int n = A.length; int res = Integer.MAX_VALUE; for (int i = 0; i < Y; i++) { int left = i, right = i; int sum = 0; int count = 0; while (right < n) { sum += A[right]; right += Y; count++; if(count == X) { res = Math.min(res, sum); sum -= A[left]; left += Y; count--; } } } return res; }
718. 最长重复子数组
难度中等
给两个整数数组 nums1
和 nums2
,返回 两个数组中 公共的 、长度最长的子数组的长度 。
示例 1:
输入:nums1 = [1,2,3,2,1], nums2 = [3,2,1,4,7] 输出:3 解释:长度最长的公共子数组是 [3,2,1] 。
示例 2:
输入:nums1 = [0,0,0,0,0], nums2 = [0,0,0,0,0] 输出:5
提示:
1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 100
https://leetcode.cn/problems/maximum-length-of-repeated-subarray/solution/zui-chang-zhong-fu-zi-shu-zu-by-leetcode-solution/
方法2 滑动窗口
class Solution { public int duiqi(int a[],int b[],int adda,int addb,int l){ int ret =0,k=0; for(int i=0;i<l;i++){ if(a[adda+i]==b[addb+i]) { k++; } else{ k =0; } ret =Math.max(ret,k); } return ret; } public int findLength(int[] nums1, int[] nums2) { int n1 = nums1.length; int n2 =nums2.length; int ans = 0; for(int i=0;i<n1;i++){ int l =Math.min(n2,n1-i); ans = Math.max(ans,duiqi(nums1,nums2,i,0,l)); } for(int i=0;i<n2;i++){ int l =Math.min(n1,n2-i); ans = Math.max(ans,duiqi(nums1,nums2,0,i,l)); } return ans; } }
220. 存在重复元素 III
难度困难
给你一个整数数组 nums
和两个整数 k
和 t
。请你判断是否存在 两个不同下标 i
和 j
,使得 abs(nums[i] - nums[j]) <= t
,同时又满足 abs(i - j) <= k
。
如果存在则返回 true
,不存在返回 false
。
https://leetcode.cn/problems/contains-duplicate-iii/solution/gong-shui-san-xie-yi-ti-shuang-jie-hua-d-dlnv/
滑动窗口+二分
class Solution { public boolean containsNearbyAlmostDuplicate(int[] nums, int indexDiff, int valueDiff) { TreeSet<Long>set =new TreeSet<>(); Long t =valueDiff*1L; for(int i=0;i<nums.length;i++){ Long u = nums[i]*1L;
找到小于等于 u 的最大值(小于等于 u 的最接近 u 的数) Long l = set.floor(u);
找到大于等于 u 的最小值(大于等于 u 的最接近 u 的数) Long r =set.ceiling(u); if(l!=null&&u-l<=t) return true; if(r!=null&&r-u<=t) return true; set.add(u); if(i>=indexDiff) set.remove(nums[i-indexDiff]*1L); 移除下标范围不在 [max(0, i - k), i) 的数 。维护大小为K的窗口 } return false; } }