LeetCode算法练习:双指针计算三数之和和四数之和

通过双指针将时间复杂度降一个级别。

java 复制代码
public class TOP {
    //15. 三数之和
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        int n = nums.length;
        if (n < 3) {
            return res;
        }
        Arrays.sort(nums);
        //先确定一个值,再用双指针找另外两个,并去重
        for (int i = 0; i < n; i++) {
            //去除无效值
            if (nums[i] > 0) break;
            //第一个数字去重
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            int left = i + 1;
            int right = n - 1;
            //双指针计算另外两个数字
            while (left < right) {
                int sum = nums[i] + nums[left] + nums[right];
                //不满足条件,缩小窗口
                if (sum > 0) {
                    right--;
                } else if (sum < 0) {
                    left++;
                } else {
                    //找到一个结果
                    res.add(Arrays.asList(nums[i], nums[left], nums[right]));
                    //对另外两个数字去重
                    while (left < right && nums[left] == nums[left + 1]) left++;
                    while (left < right && nums[right] == nums[right - 1]) right--;
                    left++; //移动到不重复区
                    right--;
                }
            }
        }
        return res;
    }

    //18. 四数之和
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList<>();
        int n = nums.length;
        if (nums.length < 4) {
            return res;
        }
        //排序来剪枝
        Arrays.sort(nums);
        //先确定2个值,再用双指针找另外两个,并去重
        for (int i = 0; i < n; i++) {
            //去除无效值 (也可以排除[1000000000,1000000000,1000000000,1000000000]溢出情况)
            if (nums[i] > 0 && nums[i] > target) break;
            //第一个数字去重
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            for (int j = i + 1; j < n; j++) {
                //第2个数字去重
                if (j > i + 1 && nums[j] == nums[j - 1]) continue;
                int left = j + 1;
                int right = n - 1;
                //双指针计算另外两个数字
                while (left < right) {
                    //防止int溢出
                    long sum = nums[i] + nums[j] + nums[left] + nums[right];
                    //不满足条件,缩小窗口
                    if (sum > target) {
                        right--;
                    } else if (sum < target) {
                        left++;
                    } else {
                        //找到一个结果
                        res.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
                        //对另外两个数字去重
                        while (left < right && nums[left] == nums[left + 1]) left++;
                        while (left < right && nums[right] == nums[right - 1]) right--;
                        left++;
                        right--;
                    }
                }
            }
        }
        return res;
    }
}
相关推荐
vlln5 分钟前
适应性神经树:当深度学习遇上决策树的“生长法则”
人工智能·深度学习·算法·决策树·机器学习
与己斗其乐无穷1 小时前
数据结构(2)线性表-顺序表
数据结构
冲帕Chompa1 小时前
图论part09dijkstra算法
算法·图论
·云扬·1 小时前
【PmHub后端篇】PmHub中基于Redis加Lua脚本的计数器算法限流实现
redis·算法·lua
周Echo周1 小时前
20、map和set、unordered_map、un_ordered_set的复现
c语言·开发语言·数据结构·c++·算法·leetcode·list
zkmall1 小时前
推荐算法工程化:ZKmall模板商城的B2C 商城的用户分层推荐策略
算法·机器学习·推荐算法
小青龙emmm1 小时前
数据结构(一) 绪论
数据结构
矿渣渣2 小时前
AFFS2 的 `yaffs_ext_tags` 数据结构详解
数据结构·算法·文件系统·yaffs2
workflower2 小时前
使用谱聚类将相似度矩阵分为2类
人工智能·深度学习·算法·机器学习·设计模式·软件工程·软件需求
cwywsx2 小时前
Linux:进程控制2
linux·运维·算法