15.三数之和

作者 : XiaXinyu
日期 :2021-10-07

题目

理解

在给定数组中找出所有相加为0的三元组

题解1(朴素做法)

首先对数组进行排序,然后使用三层for循环来枚举出所有三元组并判断是否等于0即可

虽然这种做法的时间复杂度很高,显然是不能通过测试样例的,但是实现代码中还是有很多细节是值得注意的

代码
class Solution{
    public List<List<Integer>> threeSum(int[] nums){
        List<List<Integer>> ans = new ArrayList<>();
        Arrays.sort(nums);  //对数组进行从小到大排序
        int len = nums.length;
        for(int i = 0;i < len - 2;i ++){
          	//如果三元组中的第一个元素小于0,
          	//那么这个三元组一定小于0,
            //因为数组有序,所以直接break
            if(nums[i] > 0) break; 
            if(i > 0 && nums[i] == nums[i - 1]) continue; // 如果当前枚举到的三元组中第一个元素与上一次枚举到的第一个
          																								// 元素相等则不用进行多次枚举
            for(int j = i + 1;j < len - 1;j ++){
                if(j > i + 1 && nums[j] == nums[j - 1]) continue; // 如果当前枚举到的三元组中第二个元素与上一次枚举到的
          																												// 第二个元素相等则不用进行多次枚举
          																						
                for(int k = j + 1;k < len;k ++){   //同理
                    if(k > j + 1 && nums[k] == nums[k - 1]) continue;
                    if(nums[i] + nums[j] + nums[k] == 0){
                        ArrayList<Integer> temp = new ArrayList<>();
                        temp.add(nums[i]);
                        temp.add(nums[j]);
                        temp.add(nums[k]);
                        ans.add(temp);
                    }
                }
            }
        }
        return ans;
    }
}

时间复杂度 :O(n^3) 使用3层循环

空间复杂度 :O(1)

题解2(双指针算法)

三元组中第一个元素使用for循环遍历,剩下两个元素采用双指针算法

代码
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ans = new ArrayList<>();
        if(nums.length < 3) return ans;
        int len = nums.length;
        Arrays.sort(nums);
        for(int i = 0;i < len - 2;i ++){
            if(nums[i] > 0) break;
            if(i > 0 && nums[i] == nums[i - 1]) continue;
            for(int l = i + 1,r = len - 1;l < r; ){
                int sum = nums[i] + nums[l] + nums[r];
                if(sum < 0){
                    l ++;
                    while(l < r && nums[l] == nums[l - 1]) l ++;
                }else if(sum > 0){
                    r --;
                    while(l < r && nums[r] == nums[r + 1]) r --;
                }else{
                    ArrayList<Integer> temp = new ArrayList<>();
                    temp.add(nums[i]);
                    temp.add(nums[l]);
                    temp.add(nums[r]);
                    ans.add(temp);
                    l ++;
                    r --;
                    while(l < r && nums[l] == nums[l - 1]) l ++;
                    while(l < r && nums[r] == nums[r + 1]) r --;
                }
            }
        }
        return ans;
    }
}

时间复杂度 :O(n^2) 一层for循环结合双指针算法

空间复杂度 :O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XiaXinyuuu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值