1. 程式人生 > >【LeetCode & 劍指offer刷題】Two Sum(系列)

【LeetCode & 劍指offer刷題】Two Sum(系列)

Evernote Export

1 .   Two Sum Given an array of integers, return   indices   of the two numbers such that they add up to a specific target. You may assume that each input would have
  exactly  one solution, and you may not use the  same element twice. Example: Given nums = [2, 7, 11, 15], target = 9,   Because nums[ 0 ] + nums[ 1 ] = 2 + 7 = 9,
return [0, 1].   作為LeetCode的首題,Two Sum的名氣不小啊,正所謂平生不會TwoSum,刷盡LeetCode也枉然。記得原來在背單詞的時候,總是記得第一個單詞是abandon,結果有些人背來背去還在abandon,有時候想想刷題其實跟背GRE紅寶書沒啥太大的區別,都是一個熟練功夫,並不需要有多高的天賦,只要下足功夫,都能達到一個很不錯的水平,套用一句雞湯問來激勵下吧,“有些時候我們的努力程度根本達不到需要拼天賦的地步” (來源於部落格 //問題:陣列找兩個和為目標值的數
//方法一:雙重遍歷(類似選擇排序法中的方法),掃描到所有可能的組合 //O(n^2) O(1) 很慢186ms /* class Solution { public:     vector<int> twoSum(vector<int>& a, int target)     {         for(int i = 0; i < a.size()-1; i++)         {             for(int j = i+1; j<a.size(); j++)             {                 if(a[i]+a[j] == target) return vector<int>{i,j};             }         }         return vector<int>{-1,-1}; //表示沒有找到     } };*/ /* 方法二:一次遍歷+hash表 過程:將值+索引儲存在hash表中,每次查詢hash表中是否存在某個key(target-a[i],用成員函式find查詢即可,每次查詢花費常數時間)與當前值和為target O(n), O(n) 14ms */ #include <unordered_map> class Solution { public :     vector < int > twoSum ( vector < int >& a , int target )     {         unordered_map < int , int > table         vector < int > result ;                 for ( int i = 0 ; i < a . size (); i ++)  //遍歷陣列         {             //先找再存,這樣有先後關係,在已經存的元素中去找可以湊成2sum對的元素,防止同一個數被使用兩次             int numberToFind = target - a [ i ]; //算出要找的值,             if ( table . find ( numberToFind ) != table . end ()) //如果找得到(當找不到的時候,find函式會返回容器的末尾迭代器)             {                 result . push_back ( table [ numberToFind ]); //push索引,因為要返回索引                 result . push_back ( i );             }             else  //如果找不到時,存入hash表                 table [ a [ i ]] = i ;   //值+索引(key-value)存於hash表中,相同的元素會覆蓋前面的索引             //雜湊表無需手動重建空間,當呼叫[]符號時會自動建立空間,並賦初始值0(如果不手動賦值的話)         }         return result ;     } };   167. Two Sum II - Input array is sorted(《劍指offer》第57題) Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Note:
  • Your returned answers (both index1 and index2) are not zero-based.
  • You may assume that each input would have  exactly  one solution and you may not use the  same  element twice.
Example: Input: numbers = [2,7,11,15], target = 9 Output: [1,2] Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.   /* 問題:所給陣列為有序陣列(遞增),找和為特定值的兩個數 方法:雙指標法 過程:前後各一指標,當和小於target時,往中間移動左邊指標,當和大於target時,往中間移動右邊指標直到相遇或者等於target O(n), O(1) (由於利用了陣列有序性的特點,優於雜湊表的方法) */ class Solution { public :     vector < int > twoSum ( vector < int >& a , int target )     {         vector < int > result ;         if ( a . empty ()) return result ;                 int left = 0, right = a.size()-1;         while ( left < right )         {             if ( a [ left ] + a [ right ] < target ) left ++;             else if ( a [ left ] + a [ right ] > target ) right --;             else             {                 result . push_back ( left + 1 ); //題目要求索引以1開始                 result . push_back ( right + 1 );                 return result ;             }         }                 return result ;     } };   653 .   Two Sum IV - Input is a BST Given a Binary Search Tree and a target number, return true if there exist two elements in the BST such that their sum is equal to the given target. Example 1: Input: 5 / \ 3 6 / \ \ 2 4 7   Target = 9   Output: True Example 2: Input: 5 / \ 3 6 / \ \ 2 4 7   Target = 28   Output: False   /**  * Definition for a binary tree node.  * struct TreeNode {  *     int val;  *     TreeNode *left;  *     TreeNode *right;  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}  * };  */ /* 問題:在BST中找two sum的兩個數,判斷是否存在 方法:中序遍歷後查詢即可 O(n) O(n)(因為每個結點都會被訪問一次,故會有n次遞迴,遞迴棧的空間複雜度為o(n)) */ class Solution { public :     bool findTarget ( TreeNode * root , int k )     {         vector < int > a ; //用於存結點值                 inorder ( root , a );         int left = 0 , right = a . size ()- 1 ;         while ( left < right )         {             int sum = a [ left ] + a [ right ];             if ( sum < k ) left ++;             else if ( sum > k ) right --;             else return true ;         }         return false ;     } private :     void inorder ( TreeNode * root , vector < int >& a )     {         if ( root == nullptr ) return ;                 inorder ( root -> left , a );         a . push_back ( root -> val );         inorder ( root -> right , a );     } };