面试题题系列 -- 和为0 的三个数的组合数

题目

     给定一个数组 nums ,从中找到 和为 0 的三个数之和的组合数有多少个

  比如:    8 ,  9 , 5 ,  7,  8,-1,-3,-5,1,2

   组合数: {8,-3,-5}

                   {-3, 1 , 2}

 

思路如下:

先将数组 nums 从大到小排序。

    利用双指针法。先定位第一个指针,start 指向数组的第一个元素。 第二个指针 left 指向下标为 start + 1 的元素,第三个指针 right 指向 nums.length-1 。

     判断此时  sum = nums[ start ] + nums[ left] + nums[ right] 的大小

     若是  sum < 0, 则 left++;

     若是 sum >0, 则 right --;

    若是 sum == 0 , 则 找到该组合。

    注意要进行去重,去重原则是  

  要保证连续重复的几个元素出现时候,第一个重复的元素不要做去重,要能参与算法,否则会丢失元素

java 代码如下:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

class Solution {
               public List<List<Integer>> threeSum(int[] nums) {
        // 1 数组排序
        Arrays.sort(nums);
        for(int num:nums){
            System.out.print(num+"\t");
        }
        System.out.println();

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

        for (int i = 0; i < nums.length-2; i++) {
            while (i-1>=0 && i<nums.length-2&& nums[i-1] == nums[i]) {
                i++;
            }

            int left = i + 1;
            int right = nums.length - 1;

            //System.out.println("i= "+i+", left="+left+", right = "+right);
            while (left < right) {
                // 如果和
                if (nums[i] + nums[left] + nums[right] < 0) {
                    left++;

                } else if (nums[i] + nums[left] + nums[right] > 0) {
                    right--;

                } else if(nums[i] + nums[left] + nums[right] == 0){
                    System.out.println("i= "+i+", left="+left+", right = "+right);

                    List<Integer> subList = new ArrayList<>();
                    subList.add(nums[i]);
                    subList.add(nums[left]);
                    subList.add(nums[right]);
                    result.add(subList);
                    left++;
                    right--;
                    //去除重复数据
                    while (left < right && left-1>0 &&nums[left] == nums[left-1]) {
                        left++;
                    }
                    while (right>left && right+1<nums.length && nums[right] == nums[right + 1]) {
                        right--;
                    }
                }
            }
       }

        return result;
    }

       
}

    

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值