力扣两数之和和三数之和

个人觉得最好理解的两种做法
两数之和

 public static int[] twoSum(int[] nums, int target) {
        if (nums != null) {
            for (int i = 0; i < nums.length; i++) {
                for (int j = i + 1; j < nums.length; j++) {
                    if (nums[i] + nums[j] == target) {
                        return new int[]{i, j};
                    }
                }
            }
        }
        return null;
    }

三树之和

   public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ret=new ArrayList<>();
        Arrays.sort(nums);//排序


        for(int i=0;i<nums.length;i++){//这里i是最小的数的下标
            if(nums[i]>0){return ret;}//最小的数大于0,返回
            if(i>0&&nums[i]==nums[i-1]){continue;}//去重,相同最小的数只能出现一次

            int mid=i+1;//左边界(中间数)
            int right=nums.length-1;//右边界(最大数)
            while(mid<right){
                int sum=nums[i]+nums[mid]+nums[right];
                if(sum<0){mid++;}//三数之和小于0;将最小的下标后移
                else if (sum>0){right--;}//三数之和大于0;将最大的下标前移
                else {//三数之和等于0
                    ret.add(Arrays.asList(nums[i],nums[mid],nums[right]));
                    while(mid<right&&nums[mid+1]==nums[mid]){mid++;}//去重,相同中间数只能出现一次
                    while(mid<right&&nums[right-1]==nums[right]){right--;}//去重,相同最大数只能出现一次

                    mid++;right--;//去重后--->     中间,最后同时移动
                }
            }
        }


        return ret;
    }
  public List<List<Integer>> threeSum1(int[] nums) {
        //思路分析,让我想到了,高中时学到的一种函数思想,固定一端,保持递增,另一端,采用双指针移动进行循环匹对,力扣有查询时间限制,过滤条件一个都不能省
        List<List<Integer>> ans = new ArrayList<>();
        Arrays.sort(nums);  // 先升序排序
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > 0) {//因为排过序了,如果i对应的肯定是最小的,如果最小的都大于0,总数肯定大于0
                return ans;
            }
            if (i > 0 && nums[i] == nums[i - 1]) { //最左端的去重
                continue;
            }
            int j = i + 1;  //j 相当于左指针
            int k = nums.length - 1;  // k相当于右指针
            while (j < k) { // 在左指针和右指针第一次相遇前做判断
                int sum = nums[i] + nums[j] + nums[k];
                if (sum < 0) {//和小于0就把中间指针往后移
                    j++;
                }
                if (sum > 0) {//和大于0就把最后指针往前移
                    k--;
                }
                if (sum == 0) {//和等于0就和前面的值比较去重,同时进行下一次循环
                    ans.add(Arrays.asList(nums[i], nums[j], nums[k]));
                    while (j<k&& nums[j] == nums[j + 1]) {//中指针去重
                        j++;
                    }
                    while (j<k&&nums[k - 1] == nums[k]) {//右指针去重
                        k--;
                    }
                    j++;
                    k--;
                }
            }
        }
        return ans;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值