leetcode15 三数之和

这个题的关键在于去重,想要去重,最先想到的就是对数组或列表排序,排序后,依次以列表中的每个元素为起始值,查找后面的两个数之和等于这个起始值的负值,因为是排序后的,对于连续重复的元素,作为起始值可以直接跳过,因为再以它们为起点,也不会比第一个为起点,有更多地可能了。值得注意的是,后面两个值找到后,需要在夹逼的过程中,要注意跳过和当前值相同的元素。查找后面两个数的过程就是双指针向内逼近了。

自己的解法

class Solution {

    public List<List<Integer>> threeSum(int[] nums) {

        List<List<Integer>> resList = new ArrayList<>();

        if (nums.length < 3) {

            return resList;

        }

        // 排序,进行去重

        Arrays.sort(nums);

        for (int i = 0; i < nums.length - 2; i++) {

            if (i > 0 && nums[i] == nums[i - 1]) {

                continue;

            }

            int sum = - nums[i]; 

            int left = i + 1;

            int right = nums.length - 1; 

            while (left < right) {

                if (nums[left] + nums[right] > sum) {

                    right--;                

                } else if (nums[left] + nums[right] < sum) {

                    left++;                

                } else {

                   List<Integer> res = Arrays.asList(nums[i], nums[left], nums[right]);

                   resList.add(res);

                   right--;         

                   left++;

                   while (left < right && right < nums.length - 1  && nums[right] == nums[right + 1]) {

                        right--;

                    }

                    while (left < right && nums[left] == nums[left - 1]) {

                        left++;

                    }               

                }

            }                    

        }

        return resList;             

    }

}

进阶解法:

思路和自己的解法类似,多了个nums[i]大于0的情况下,不用再找后面两个元素。还有就是命中了以后,进行去重的时候,先判断重复进行跳过,再进行常规跳过,这样可以少个右侧溢出的判断。

class Solution {

    public static List<List<Integer>> threeSum(int[] nums) {

        List<List<Integer>> ans = new ArrayList();

        int len = nums.length;

        if(nums == null || len < 3) return ans;

        Arrays.sort(nums); // 排序

        for (int i = 0; i < len ; i++) {

            if(nums[i] > 0) break; // 如果当前数字大于0,则三数之和一定大于0,所以结束循环

            if(i > 0 && nums[i] == nums[i-1]) continue; // 去重

            int L = i+1;

            int R = len-1;

            while(L < R){

                int sum = nums[i] + nums[L] + nums[R];

                if(sum == 0){

                    ans.add(Arrays.asList(nums[i],nums[L],nums[R]));

                    while (L<R && nums[L] == nums[L+1]) L++; // 去重

                    while (L<R && nums[R] == nums[R-1]) R--; // 去重

                    L++;

                    R--;

                }

                else if (sum < 0) L++;

                else if (sum > 0) R--;

            }

        }       

        return ans;

    }

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。