圖解「小於 K 的兩數之和 」

  • 2019 年 10 月 4 日
  • 筆記

者 | P.yh

來源 | 五分鐘學演算法

題目描述

題目來源於 LeetCode 上第 1099 號問題:小於 K 的兩數之和。

給你一個整數數組 A 和一個整數 K,請在該數組中找出兩個元素,使它們的和小於 K 但儘可能地接近 K,返回這兩個元素的和。

如不存在這樣的兩個元素,請返回 -1。

示例 1:

輸入:A = [34,23,1,24,75,33,54,8], K = 60  輸出:58  解釋:  34 和 24 相加得到 58,58 小於 60,滿足題意。  

示例 2:

輸入:A = [10,20,30], K = 15  輸出:-1  解釋:  我們無法找到和小於 15 的兩個元素。  

提示:

  1. 1 <= A.length <= 100
  2. 1 <= A[i] <= 1000
  3. 1 <= K <= 2000

題目解析

傳統的 TwoSum 都是要你找到等於 target 的配對,那麼如果說要找到 大於/小於 target 的配對呢?

這個時候 Hash 表的方法就很難 work 了,因為 Hash 表比較適合處理 等於 的情況 !

那麼就需要考慮如何使用排序加雙指針的方法來解決這個問題,這裡,題目是要求小於 target 的數量,我們還是按照之前的分析思路來分析。

如果說當前左右指針指向的元素的和大於或者等於 target,那麼勢必我們需要向左移動右指針,讓兩個元素的和儘可能地小。

當前頭尾指針指向的元素和小於 target 的時候,這時我們需要記錄答案,雖然這道題目裡面沒提,如果說要記錄配對數量的話,這時並不是記錄一個答案,如果說當前左指針固定,除了當前的右指針指向的元素,在左指針和右指針之間的數都是滿足要求的,我們只需要加上這個區間的數量即可。

當然如果數組中存在重複元素,那麼我們就需要按照之前的套路遍歷去重了,當然對於這道題來說,我們選擇滿足條件的最大值即可。

動畫描述

程式碼實現

public int twoSumLessThanK(int[] A, int K) {      if (A == null || A.length == 0) {          return -1;      }        Arrays.sort(A);        int l = 0, r = A.length - 1;      int result = Integer.MIN_VALUE;        while (l < r) {          if (A[l] + A[r] >= K) {              r--;          } else {              result = Math.max(result, A[l] + A[r]);              l++;          }      }        return result == Integer.MIN_VALUE ? -1 : result;  }  

Tags: