1. 程式人生 > >leetcode刷題--兩數之和(簡單)

leetcode刷題--兩數之和(簡單)

一、序言

  第一次刷leetcode的題,之前從來沒有刷題然後去面試的概念,直到臨近秋招,或許是秋招結束的時候才有這個意識,原來面試是需要刷題的,面試問的問題都是千篇一律的,只要刷夠了題就差不多了,當然你的基礎也要紮實,畢竟在技術面的時候很容易露餡的。

  所以奉勸各位還未畢業,在大三或大二的師弟師妹早點刷題,心裡也有底氣進入求職大軍,畢竟大四開始刷題的話時間上有些太緊了,推薦刷題的話就是牛客和leetcode。

  迴歸正題,這次記錄的是leetcode刷的第一題--兩數之和

二、審題

  審題真的很重要,這道題我因為審題和慣性思維的原因導致前兩次都編寫程式的執行結果不正確。

給定一個整數陣列和一個目標值,找出陣列中和為目標值的兩個數。

你可以假設每個輸入只對應一種答案,且同樣的元素不能被重複利用。

示例:

給定 nums = [2, 7, 11, 15], target = 9
因為 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

1、整數陣列和一個目標值

    題目中的整數陣列是可以有負數正數的,例:{-10,-15,-18,0,9,55}

    目標值可能為整數陣列兩數之和,意味著可以為正數負數,例:-9 、0 、10

2、同樣的元素不能被重複利用

    例:target=6,nums={3,2,4}

    所以返回[1,2],而不是[0,0],3不可以重複利用

三、解題

1、暴力法

  遍歷每個元素 xx,並查詢是否存在一個值與 target - xtarget−x 相等的目標元素。

直接上程式碼:

 1 class Solution {
 2     public int[] twoSum(int[] nums, int target) {
 3         int[] down={-1,-1};
 4         
 5         for(int i=0;i<nums.length;i++){
 6             down[0]=i;
 7             for
(int j=i+1;j<nums.length;j++){ 8 if(nums[j]==(target-nums[i])){ 9 down[1]=j; 10 return down; 11 } 12 } 13 14 } 15 return down; 16 17 } 18 }

圖分析思路:

 

複雜度分析:

  • 時間複雜度:O(n2), 對於每個元素,我們試圖通過遍歷陣列的其餘部分來尋找它所對應的目標元素,這將耗費 O(n) 的時間。因此時間複雜度為 O(n2)。

  • 空間複雜度:O(1)。 

2、兩遍雜湊表

  這個方法我是沒有想到的,這需要記錄下來,而且我資料結構不太紮實,雜湊表也不是很清楚,自己分析總結一下。

  一個簡單的實現使用了兩次迭代。在第一次迭代中,我們將每個元素的值和它的索引新增到表中。然後,在第二次迭代中,我們將檢查每個元素所對應的目標元素(target - nums[i]targetnums[i])是否存在於表中。注意,該目標元素不能是 nums[i]nums[i] 本身!

直接上程式碼:

 1 public int[] twoSum(int[] nums, int target) {
 2     Map<Integer, Integer> map = new HashMap<>();
 3     for (int i = 0; i < nums.length; i++) {
 4         map.put(nums[i], i);
 5     }
 6     for (int i = 0; i < nums.length; i++) {
 7         int complement = target - nums[i];
 8         if (map.containsKey(complement) && map.get(complement) != i) {
 9             return new int[] { i, map.get(complement) };
10         }
11     }
12     throw new IllegalArgumentException("No two sum solution");

圖分析思路:

複雜度分析:

 

  • 時間複雜度:O(n), 我們把包含有 個元素的列表遍歷兩次。由於雜湊表將查詢時間縮短到 O(1) ,所以時間複雜度為 O(n)

  • 空間複雜度:O(n), 所需的額外空間取決於雜湊表中儲存的元素數量,該表中儲存了 n 個元素。

3、一遍雜湊表

  哈哈哈哈哈哈哈哈哈,這個方法我也搞不太懂,貼上來參考一下吧!!!!

  在進行迭代並將元素插入到表中的同時,我們還會回過頭來檢查表中是否已經存在當前元素所對應的目標元素。如果它存在,那我們已經找到了對應解,並立即將其返回。

直接上程式碼:

 1 public int[] twoSum(int[] nums, int target) {
 2     Map<Integer, Integer> map = new HashMap<>();
 3     for (int i = 0; i < nums.length; i++) {
 4         int complement = target - nums[i];
 5         if (map.containsKey(complement)) {
 6             return new int[] { map.get(complement), i };
 7         }
 8         map.put(nums[i], i);
 9     }
10     throw new IllegalArgumentException("No two sum solution");
11 }

複雜度分析:

  • 時間複雜度:O(n), 我們只遍歷了包含有 nn 個元素的列表一次。在表中進行的每次查詢只花費 O(1) 的時間。

  • 空間複雜度:O(n), 所需的額外空間取決於雜湊表中儲存的元素數量,該表最多需要儲存 個元素。