滑动窗口(5题)

本文介绍了五种Java编程挑战,涉及滑动窗口算法、哈希集、字符串操作、最长和谐子序列和子数组最大平均数。展示了高效解决这些问题的代码片段,并强调了内存优化和时间复杂度的实战技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

219. 存在重复元素 II

//执行用时:14 ms, 在所有 Java 提交中击败了97.36%的用户
    //内存消耗:50 MB, 在所有 Java 提交中击败了45.06%的用户
    //通过测试用例:51 / 51
    //滑动窗口+hashset---------------------通过
    public static boolean containsNearbyDuplicate1(int[] nums, int k) {
        Set<Integer> set = new HashSet<Integer>();
        for (int i = 0; i < nums.length; i++) {
            if (i > k) {
                set.remove(nums[i - k - 1]);   //不断删除滑动窗口的首元素
            }
            if (!set.add(nums[i])) {   //假如在窗口中有重复的元素返回false----!false--》true---返回true
                return true;        //因为abs(i - j) <= k----所以要判断添加进窗口内部的所有元素--有重复则满足
            }
        }
        return false;
    }

1208. 尽可能使字符串相等

//执行用时:6 ms, 在所有 Java 提交中击败了60.47%的用户
    //内存消耗:41.5 MB, 在所有 Java 提交中击败了5.10%的用户
    //通过测试用例:37 / 37
    public static int equalSubstring(String s, String t, int maxCost) {
        int[] num = new int[s.length()];
        for (int i = 0; i < s.length(); i++) {
            num[i] = Math.abs(s.charAt(i) - t.charAt(i));
        }
        int max = 0;   //统计长度
        int sum = 0;
        int start = 0;   //前指针
        int end = 0;     //后指针
        while (end < s.length()){
            sum += num[end];
            while (sum > maxCost){   //超过就判断
                sum = sum - num[start];  //从头删除符合条件的元素
                start++;
            }
            max = Math.max(max,end-start +1);
            end++;        //一直跑指针
        }
        return max;
    }

594. 最长和谐子序列

//执行用时:13 ms, 在所有 Java 提交中击败了96.37%的用户
    //内存消耗:42.8 MB, 在所有 Java 提交中击败了5.02%的用户
    //通过测试用例:206 / 206
    //排序+双指针
    public static int findLHS(int[] nums) {
        int[] nums1 = Arrays.copyOf(nums,nums.length);
        Arrays.sort(nums1);
        int start = 0;   //前指针
        int n = 0;    //统计个数的
        for (int end = 0;end<nums1.length;){
            while (end < nums1.length && (nums1[end] == nums1[start] || nums1[end] - nums1[start] == 1)){
                end++;
            }
            if (nums1[end-1] - nums1[start] == 1){
                n = Math.max(n,end-start);
            }
            start++;
        }
        return n;
    }

643. 子数组最大平均数 I

//执行用时:2 ms, 在所有 Java 提交中击败了100.00%的用户
    //内存消耗:48.9 MB, 在所有 Java 提交中击败了94.67%的用户
    //通过测试用例:127 / 127

    //滑动窗口----通用模板
    public static double findMaxAverage(int[] nums, int k) {
        int sum = 0;
        for (int i = 0; i < k; i++) {
            sum += nums[i];    //定义一个滑动窗口
        }
        int max = sum;
        for (int i = k; i < nums.length; i++) {
            sum = sum - nums[i - k] + nums[i];   //减去窗口的第一个值并加上下一个值----达到移动窗口
            max = Math.max(max, sum);
        }
        return (double) max / (double)k;
    }

1423. 可获得的最大点数

 //执行用时:2 ms, 在所有 Java 提交中击败了77.13%的用户
    //内存消耗:49.8 MB, 在所有 Java 提交中击败了5.26%的用户
    //通过测试用例:40 / 40
    //滑动窗口
    public static int maxScore(int[] cardPoints, int k) {
        int sum = 0;
        for (int i = 0;i < k;i++){    //维护个窗口---先装右边的
            sum+=cardPoints[i];
        }
        int max = sum;
        for (int i = 0;i < k-1;i++){    //拿左边的后面的值 与 右边的值互换取最大值
            sum = sum - cardPoints[k-1-i] + cardPoints[cardPoints.length-1-i];
            max = Math.max(max,sum);
        }
        return max;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值