原版 sorted面試
[抄題]:算法
[思惟問題]:數組
存sum - nums[i](補集),若出現第二次則調出數據結構
[一句話思路]:ide
hashmap中,重要的數值當作key,角標當作value.網站
[畫圖]:spa
[一刷]:設計
[總結]:指針
[複雜度]:n/ncode
[英文數據結構,爲何不用別的數據結構]:
2根指針 n^2
[其餘解法]:2根指針 j=i + 1
[題目變變變]:
class Solution { public int[] twoSum(int[] nums, int target) { int[] result = new int[2]; HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); for (int i = 0; i < nums.length; i++) { if (map.containsKey(target - nums[i])) { result[0] = map.get(target - nums[i]); result[1] = i; return result; } map.put(nums[i],i); } return result; } }
closest
[抄題]:
找到兩個數字使得他們和最接近target
[思惟問題]:
j = i + 1, 複雜度平方,不行
[一句話思路]:
排序後,兩根指針都往中間走,能比較大小。下降複雜度。
[畫圖]:
[一刷]:
[總結]:一樣是兩根指針,用排序能夠下降遍歷的複雜度
[複雜度]:兩根指針是n^2/1
[英文數據結構,爲何不用別的數據結構:
[其餘解法]:
[題目變變變]:(都用的排序)返回和小於等於、大於target的對數;3 sum closest
/** * 本參考程序來自九章算法,由 @九章算法 提供。版權全部,轉發請註明出處。 * - 九章算法致力於幫助更多中國人找到好的工做,教師團隊均來自硅谷和國內的一線大公司在職工程師。 * - 現有的面試培訓課程包括:九章算法班,系統設計班,算法強化班,Java入門與基礎算法班,Android 項目實戰班, * - Big Data 項目實戰班,算法面試高頻題班, 動態規劃專題班 * - 更多詳情請見官方網站:http://www.jiuzhang.com/?source=code */ public class Solution { /** * @param nums an integer array * @param target an integer * @return the difference between the sum and the target */ public int twoSumClosest(int[] nums, int target) { if (nums == null || nums.length < 2) { return -1; } Arrays.sort(nums); int left = 0, right = nums.length - 1; int diff = Integer.MAX_VALUE; while (left < right) { if (nums[left] + nums[right] < target) { diff = Math.min(diff, target - nums[left] - nums[right]); left++; } else { diff = Math.min(diff, nums[left] + nums[right] - target); right--; } } return diff; } }
返回小於、大於的對數
[抄題]:
給定一個整數數組,找出這個數組中有多少對的和是小於或等於目標值。返回對數。
[思惟問題]:
不理解cnt爲何是right - left,由於中間的數其實均可以。
有數組先排序。
[一句話思路]:
相似於closest,兩邊都往中間靠,調節sum的大小。
[畫圖]:
[一刷]:
[總結]:
用排序下降複雜度,兩邊往中間靠。
[複雜度]:
[英文數據結構,爲何不用別的數據結構]:
[其餘解法]:
[題目變變變]:
public Class Solution { public int twoSums5(int[] nums, int target) { if (nums.length < 2 || nums.length == null) { return 0; } int left = 0; int right = nums.length - 1; int cnt = 0; Arrays.sort(nums);// while(left < right) { int v = nums[left] + nums[right]; if (v <= target) { left ++; } else { cnt += right - left; right —; } } return cnt; } }
組成不一樣的對數
[抄題]:
給一整數數組, 找到數組中有多少組 不一樣的元素對
有相同的和, 且和爲給出的 target 值, 返回對數.
[思惟問題]:
不知道左右兩個指針移動多少。實際上是切入點不對:直接從目標v = target切入,大了right--, 小了left++。
corner case是連續的值都相等,nums[right] == nums[right + 1],沒想到。
[一句話思路]:
[畫圖]:
[一刷]:
[總結]:
closest,小於或大於的對數,組成不一樣的對數 都是排序+兩根指針的作法
[複雜度]:
[英文數據結構,爲何不用別的數據結構]:
[其餘解法]:
[題目變變變]:
public class Solution { public int twoSum6(int nums[], int target) { if (nums.length < 2 || nums == null) { return 0; } Arrays.sort(nums); int left = 0; int right = nums.length - 1; int count = 0; int v = nums[left] + nums[right]; while(left < right) { if (v == target) { left++; right—; count++; } while((left < right) && (nums[right] == nums[right + 1])) { right—;// } while((left < right) && (nums[left] == nums[left - 1])) { left++; } } else if(v > target) { right—; } else { left++; } return count; } }