• 3Sum Closest


    描述

    给定一个n个整数的数组SS中找到三个整数,使得总和最接近给定数量的目标。返回三个整数的和。你可以假设每个输入都只有一个解决方案。

        例如,给定数组S = {-1 2 1 -4},target = 1。
    
        最接近目标的总和是2.(-1 + 2 + 1 = 2)。
    

    解决方案

    和上次做的三个数和为0那个题很像,所以首先要想到的当然就是给这个无序数组排序,这样能降低之后的匹配过程的复杂度。

    我又一次本着先做对后看事件复杂度的态度,先按照最传统的方法做出来了,惊喜的是,通过了,虽然时间复杂度还是很高,下面是我写的方法:

    public int threeSumClosest(int[] nums, int target) {
            Arrays.sort(nums);
            int distance = Math.abs(target-(nums[0]+nums[1]+nums[2]));
            int sum = nums[0]+nums[1]+nums[2];
            for(int i=0; i<nums.length-2;i++){
                if(i == 0 || (i > 0 && nums[i] != nums[i-1])){
                    for(int j=i+1; j<nums.length-1; j++){
                        if(j == (i+1) || (j > (i+1) && nums[j] != nums[j-1])){
                            for(int n=j+1; n<nums.length; n++){
                                if((n == (j+1) || (n > (j+1) && nums[n] != nums[n-1])) && (distance>Math.abs(target-(nums[i]+nums[j]+nums[n])))){
                                    distance = Math.abs(target-(nums[i]+nums[j]+nums[n]));
                                    sum = nums[i]+nums[j]+nums[n];
                                }
                            }
                        }
                    }
                }
            }
            return sum;
        }
    

    然后看了讨论区中大神们做的,很厉害,其方法还是利用之前那个从两边趋近中间的方法,思想如下:

    1、先定义第一个数的位置,然后再以第一个数右边一位的数为最左数,以最后一位数为最右数。

    2、把第一个数,最左数和最右数这三个数加和。

    3、如果此时三个数的和大于目标数,那么说明最右数过大,那么最右数向左移动一位。重复步骤2。

    4、如果三个数和小于目标数,那么说明最左数过小,那么最左数右移动一位。重复步骤2。

    5、在进行2/3/4步骤同时,比较最短距离和记录三个数的和,以便最后得到正确结果并返回。

    具体代码如下:

    public int threeSumClosest1(int[] num, int target) {
            int result = num[0] + num[1] + num[num.length - 1];
            Arrays.sort(num);
            for (int i = 0; i < num.length - 2; i++) {
                int start = i + 1, end = num.length - 1;
                while (start < end) {
                    int sum = num[i] + num[start] + num[end];
                    //如果此时三个数和大于target,说明最大数过大(即num[end]过大),那么就要减小大数,否则增大小的数(即num[start]过小)
                    if (sum > target) {
                        end--;
                    } else {
                        start++;
                    }
                    if (Math.abs(sum - target) < Math.abs(result - target)) {
                        result = sum;
                    }
                }
            }
            return result;
        }
    

      

  • 相关阅读:
    systemctl启动服务时,配置日志输出控制
    HTML5实现大文件分片上传示例
    HTML5实现大文件分片上传实例
    HTML5实现大文件分片上传代码
    HTML5实现大文件分片上传源代码
    HTML5实现大文件分片上传源码
    如何将word内容粘贴到富文本编辑器里面
    UEditor可以如何直接复制word的图文内容到编辑器中
    WORD 图片能粘到百度编辑器吗
    Word文档粘贴到DEDECMS
  • 原文地址:https://www.cnblogs.com/K-artorias/p/7911795.html
Copyright © 2020-2023  润新知