【算法】day2 双指针+滑动窗口

1、三数之和(单调性,相撞)

题目:15. 三数之和 - 力扣(LeetCode)

思路:注意,组合不能重复。

代码:

java 复制代码
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ret = new ArrayList<>();
        // 排序
        Arrays.sort(nums);
        int len = nums.length;
        // 双指针
        for(int i = 0; i <= len-3 && nums[i] <= 0;) {
            int left = i+1;
            int right = len-1;
            while(left < right) {
                int sum = nums[i] + nums[left] + nums[right];
                if(sum > 0) {
                    right--;
                    // 去重
                    while(left < right && nums[right] == nums[right +1]) right--;
                } else if(sum < 0) {
                    left++;
                    // 去重
                    while(left < right && nums[left] == nums[left-1]) left++;
                } else {
                    ret.add(Arrays.asList(nums[i], nums[left], nums[right]));
                    left++;
                    right--;
                    // 去重
                    while(left < right && nums[left] == nums[left-1]) left++;
                    while(left < right && nums[right] == nums[right +1]) right--;
                }
            }
            i++;
            // 去重
            while(i <= len-3 && nums[i] == nums[i-1]) i++;
        }
        return ret;
    }
}

时间:n^2

2、四数之和(单调性,相撞)

题目:18. 四数之和 - 力扣(LeetCode)

思路:与三数之和相似。

代码:这道题算四数 sum 有可能超过 int 的最大值 2147483647,把 sum 的类型改为 long,把第一个计算数强转为 long,后面的数字运算会自动类型提升为 long。

java 复制代码
class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);
        List<List<Integer>> ret = new ArrayList<>();
        int len = nums.length;
        for(int i = 0; i <= len - 4;) {
            for(int j = i+1; j <= len-3;) {
                int left = j+1;
                int right = len-1;
                while(left < right) {
                    long sum = (long)nums[i] + nums[j] + nums[left] + nums[right];
                    if(sum > target) {
                        right--;
                        while(left < right && nums[right] == nums[right+1]) right--;
                    } else if(sum < target) {
                        left++;
                        while(left < right && nums[left] == nums[left-1]) left++;
                    } else {
                        System.out.println(sum);
                        ret.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
                        left++;
                        right--;
                        while(left < right && nums[left] == nums[left-1]) left++;
                        while(left < right && nums[right] == nums[right+1]) right--;
                    }
                }
                j++;
                while(j <= len-3 && nums[j] == nums[j-1]) j++;
            }
            i++;
            while(i <= len-4 && nums[i] == nums[i-1]) i++;
        }
        return ret;
    }
}

3、长度最小的子数组(滑动窗口)

(1)什么是滑动窗口

即同向双指针。left 和 right 之间的区间,像一个窗口,往一个方向滑动。

(2)什么时候用滑动窗口

暴力枚举时,可以发现单调性,让左右指针同向滑动。

(3)怎么用滑动窗口

1、初始化:left=right=0

2、进窗口:left 滑动

3、出窗口:right 滑动

4、更新结果,具体放在哪个位置,根据具体情况而定。

(4)解题

题目:209. 长度最小的子数组 - 力扣(LeetCode)

思路:

代码:

java 复制代码
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int n = nums.length;
        int sum = 0;
        int min_len = Integer.MAX_VALUE;
        for(int left=0, right=0; right < n; right++) {
            // 入窗口
            sum += nums[right];
            while(sum >= target) {
                // 更新结果
                min_len = Math.min(min_len, right-left+1);
                // 出窗口
                sum -= nums[left++];
            }
        }
        return min_len == Integer.MAX_VALUE ? 0 : min_len;
    }
}
相关推荐
luj_17683 分钟前
大航海时代:沉浸式财商实战沙盒
c语言·开发语言·网络·经验分享·算法
Navigator_Z24 分钟前
LeetCode //C - 1200. Minimum Absolute Difference
c语言·算法·leetcode
wabs66635 分钟前
关于字符串【力扣344.反转字符串的思考】
数据结构·算法·leetcode
LuminousCPP40 分钟前
数据结构基础篇(二):顺序表与链表全方位对比|从内存布局到 CPU 缓存理解底层差异
c语言·数据结构·经验分享·链表·缓存
有点。1 小时前
C++二叉树(一)
开发语言·数据结构·c++
民乐团扒谱机2 小时前
【微实验】谐波乘积谱(HPS)算法深度解析:原理、数学与代码实现
开发语言·人工智能·python·算法·语音识别·音乐
Nil2082 小时前
leetcode 73矩阵置0
算法·leetcode·矩阵
Lazionr2 小时前
stack与queue:底层实现与容器适配器
开发语言·数据结构·c++
原野池予3 小时前
深入Java集合框架:数组与List互转底层原理剖析(JDK 8)
java·数据结构·list
今日无bug3 小时前
列表转树:一道题搞懂 HashMap 在算法里的价值
前端·数据结构