演算法學習100天——10 雙指標
阿新 • • 發佈:2022-03-09
題目地址(167. 兩數之和 II - 輸入有序陣列)
https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/
題目描述
給你一個下標從 1 開始的整數陣列 numbers ,該陣列已按 非遞減順序排列 ,請你從陣列中找出滿足相加之和等於目標數 target 的兩個數。如果設這兩個數分別是 numbers[index1] 和 numbers[index2] ,則 1 <= index1 < index2 <= numbers.length 。 以長度為 2 的整數陣列 [index1, index2] 的形式返回這兩個整數的下標 index1 和 index2。 你可以假設每個輸入 只對應唯一的答案 ,而且你 不可以 重複使用相同的元素。 你所設計的解決方案必須只使用常量級的額外空間。 示例 1: 輸入:numbers = [2,7,11,15], target = 9 輸出:[1,2] 解釋:2 與 7 之和等於目標數 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。 示例 2: 輸入:numbers = [2,3,4], target = 6 輸出:[1,3] 解釋:2 與 4 之和等於目標數 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。 示例 3: 輸入:numbers = [-1,0], target = -1 輸出:[1,2] 解釋:-1 與 0 之和等於目標數 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。 提示: 2 <= numbers.length <= 3 * 104 -1000 <= numbers[i] <= 1000 numbers 按 非遞減順序 排列 -1000 <= target <= 1000 僅存在一個有效答案
解題思路
這個題和1.兩數之和很像,但是這題返回的是兩個數,就用到了昨天的一開始的思路—雙指標
利用雙指標,可以O(N)時間複雜度解決問題
優化:雙指標遍歷,最差是O(N),原理是選定一個數,查詢另一個滿足條件的數,既然是查詢,就想到了二分法,所以可以每次二分查詢一個數,判斷是否滿足條件,再根據情況調整
程式碼(雙指標)
class Solution { public int[] twoSum(int[] numbers, int target) { for(int left = 0, right = numbers.length - 1; left < right; ){ if(numbers[left] + numbers[right] == target){ return new int[]{left + 1, right + 1}; } if(numbers[left] + numbers[right] < target){ left ++; }else{ right --; } } return null; } }
結果
執行用時:1 ms, 在所有 Java 提交中擊敗了75.29%的使用者
記憶體消耗:44.5 MB, 在所有 Java 提交中擊敗了5.12%的使用者
程式碼(二分查詢優化後)
class Solution { public int[] twoSum(int[] numbers, int target) { for(int left = 0, right = numbers.length - 1; left < right; ){ int m = ((right - left) >> 1) + left; if(numbers[m] + numbers[right] < target){ left = m + 1; }else if(numbers[left] + numbers[m] > target){ right = m - 1; }else if(numbers[left] + numbers[right] < target){ left ++; }else if(numbers[left] + numbers[right] > target){ right --; }else{ return new int[]{left + 1, right + 1}; } } return null; } }
結果
執行用時:0 ms, 在所有 Java 提交中擊敗了100.00%的使用者
記憶體消耗:44.1 MB, 在所有 Java 提交中擊敗了14.95%的使用者