leetcode15.三数之和——学习笔记

题目:力扣icon-default.png?t=L9C2https://leetcode-cn.com/problems/3sum/

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        for(int i=0;i<nums.length;i++){
            if(nums[i] > 0) return ans;
            if(i > 0 && nums[i] == nums[i-1]) continue;
            int left = i+1;
            int right = nums.length-1;
            while(left<right){
                if(nums[i]+nums[left]+nums[right]==0){
                    List<Integer> list = new ArrayList<>();
                    list.add(nums[i]);
                    list.add(nums[left]);
                    list.add(nums[right]);
                    ans.add(list);
                    while(left<right && nums[left+1]==nums[left]) left++;
                    while(left<right && nums[right-1]==nums[right]) right--;
                    left++;
                    right--;
                }else if(nums[i]+nums[left]+nums[right]>0){
                    right--;
                }else{
                    left++;
                }
            }
        }
        return ans;
    }
}

 

 思路:这题一直超时,很久都AC不了,很难受。这里大概思路是,想给传入的数组先排序,然后枚举第一个数,再利用双指针的算法找是否存在三数之和为0的元素,若有则通过add()的方法添加进list中。双指针的位置范围再枚举元素与最后一个元素之间,这样既可以避免了重复解,又节省了运行时间。遍历枚举完成后,返回ans即可。

1.准备阶段。给传入数组排序,然后声明一个二维的lis类对象ans。

Arrays.sort(nums);
List<List<Integer>> ans = new ArrayList<List<Integer>>();

2.枚举第一个数。

for(int i=0;i<nums.length;i++){
    //......
}

3.避免枚举重复的元素导致重复解。设置左指针与右指针的位置。

if(i > 0 && nums[i] == nums[i-1]) continue;
int left = i+1;
int right = nums.length-1;

4.双指针循环查找符合三数之和为0的元素。若找到,则通过add()的方法添加到list中,然后左右指针继续靠近,继续查找解。其中两个while语句是为了保证左右指针不会找到与之前重复的元素,从而导致重复解。如果没有匹配成功,则根据三数之和的大小判断是移动左指针还是移动右指针。若三数之和大于0,则将右指针向左移;若三数之和小于0,则将左指针向右移。

while(left<right){
    if(nums[i]+nums[left]+nums[right]==0){
        List<Integer> list = new ArrayList<>();
        list.add(nums[i]);
        list.add(nums[left]);
        list.add(nums[right]);
        ans.add(list);
        while(left<right && nums[left+1]==nums[left]) left++;
        while(left<right && nums[right-1]==nums[right]) right--;
        left++;
        right--;
    }else if(nums[i]+nums[left]+nums[right]>0){
        right--;
    }else{
        left++;
    }
}

5.完成上述循环,返回ans即可。

return ans;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Hokachi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值