三数之和(双指针法)

问题描述:

//    给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
//
//        注意:答案中不可以包含重复的三元组。
//
//        例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
//
//        满足要求的三元组集合为:
//        [
//          [-1, 0, 1],
//          [-1, -1, 2]
//        ]
//
//        来源:力扣(LeetCode)
//        链接:https://leetcode-cn.com/problems/3sum
//        著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解决方案:

对于该问题主要得难点在于去重。

先对该数组原地升序排序。

定义i 为第一个值的下标,left 为第二个值的下标,right为第三个值的下标

i从0到nums.length - 3 依次遍历:

       对于每一个i,left初值为i+1,right初值为nums.length - 1 

        当 left  < right时 

              计算target = nums[i] + nums[left] + nums[right]

              当target > 0时说明此时三数之和过大了,right左移

              target < 0时,left右移

              target == 0说明就是这三个数,但是此时还是不能退出,中间数还是可能存在可行解的。right--  left++

如上只是说了双指针法的大体思路,并未提出去重的解决方案

对于第一个数nums[i],若nums[i] == nums[i - 1],说明这个值之前已经作为第一个数遍历过了 应该跳过这个数,continue即可

对于第二个数nums[left] 若nums[left] == nums[left - 1]同理,跳过这个数即可

第三个数nums[right],若nums[right] == nums[right + 1] 同理

此外由于该数组是排好序的数组,因此dangnums[i] > 0时,意味着i后面的都是大于0的,因此便不存在以nums[i]为第一个数的可行解。整体退出即可。

具体实现代码如下:

     public List<List<Integer>> threeSum(int[] nums) {
         List<List<Integer>> list = new LinkedList<>();
         Arrays.sort(nums);
         for (int i = 0; i < nums.length - 2; i++) {
             if(nums[i] > 0) {
                 break;
             }
             if(i > 0 && nums[i] == nums[i - 1]) {
                 continue;
             }
             int left = i + 1;
             int right = nums.length - 1;
             while(left < right) {
                 if(left > i + 1 && nums[left] == nums[left - 1]) {
                     left++;
                     continue;
                 }
                 if(right < nums.length - 1 && nums[right] == nums[right + 1]) {
                     right--;
                     continue;
                 }
                 int target = nums[i] + nums[left++] + nums[right--];
                 if (target > 0) {
                     right--;
                 } else if(target < 0) {
                     left++;
                 } else {
                     List<Integer> temp = new LinkedList<>();
                     temp.add(nums[i]); temp.add(nums[left]); temp.add(nums[right]);
                     list.add(temp);
                 }
             }
         }
         return list;
     }
发布了38 篇原创文章 · 获赞 4 · 访问量 2131

猜你喜欢

转载自blog.csdn.net/gw_9527/article/details/103812059