双指针算法题之最接近的三数之和

358 阅读1分钟

最大花费金额

  • 在一堆商品中买三个,使商品总额最接近持有金额,但不能超过。如果持有金额不够买三个商品,返回-1

  • 输入描述:

    • 第一行输入n个商品价格,用空格隔开
    • 第二行输入一个金额t
  • 输出描述:最接近持有金额的商品总额或-1

0 < n <=1000
0 < t <= 1000
复制代码

例一:

  • 输入:

    • 23 33 22 18
    • 65
  • 输出:63

  • 解释:可以购买 23 + 22 + 18 = 63

例二:

  • 输入:

    • 23 33 22 18
    • 62
  • 输出:-1

  • 解释:持有金额不够买三个商品。

算法思路如下: 1.将当前数组按升序排序得到数组(newArr),定义个变量存数组前三项之和 sum = newArr[0]+newArr[1]+newArr[2]; 2.遍历排序后的数组,同时定义一个头指针为 start = 0和一个尾指针end = newArr.length - 1; 3.在遍历过程中碰到(头指针start == 当前数组下标)或者 (尾指针end == 当前数组的下标) 则跳过(continue); 4.定义个变量curSum存三数之和(newArr[start] + newArr[i] + newArr[end]),若curSum的值大于目标值target的话,则需要取小一点的值,即end--;若curSum的值小于目标值target的话,则需要取大一点的值,即start++; 5.比较 target - curSum的绝对值和 target - sum的绝对值的大小,哪个小就取哪个值; 6.循环结束的时候返回sum;

    function threeSumNear(nums, target) {
        if(!nums || nums && nums.length<3) return -1;
       let newArr = nums.sort((a,b)=>a-b),
           sum = newArr[0] + newArr[1] + newArr[2],
           start = 0, end = newArr.length - 1;
           for(let i = 0;i<newArr.length;i++) {
               while(start < end) {
                    if(start == i) {
                       start++;
                       continue;
                   }
                   if(end == i){
                        end--;
                        continue;
                    }
                   let curSum = newArr[start] + newArr[i] + newArr[end];
                    curSum < target ? start++ : end --;
                    sum = Math.abs(target - curSum) < Math.abs(target - sum) ? curSum : sum;
                }
           }
       return sum > target ? -1 : sum;
    }