Leetcode每日一道 -- 兩數之和
阿新 • • 發佈:2018-11-24
題目連結: https://leetcode-cn.com/problems/two-sum/description/
題目描述:
給定一個整數陣列 nums 和一個目標值 target,請你在該陣列中找出和為目標值的 兩個 整數。
你可以假設每種輸入只會對應一個答案。但是,你不能重複利用這個陣列中同樣的元素。
示例:
給定 nums = [2, 7, 11, 15], target = 9
因為 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
題目分析 : 最直觀想法是暴力搜尋,複雜度是O(N^2),但是這樣是不過的。還有一種方式是排序之後,利用雙指標方法進行搜尋,複雜度是O(n*lgn),依然很複雜。比較理想的想法是看到一個數字能夠快速找到 target-nums[i] 是否在陣列中,本質上是一個檢索問題,最快的查詢方式就是利用Hash對映查詢。Python中的set是基於Hash對映進行查詢的,在C++中unorder_map是基於Hash對映進行查詢的。程式碼如下:
class Solution: def twoSum(self, nums, target): """ :type nums: List[int] :type target: int :rtype: List[int] """ nums_set=set(nums) #將nums轉為集合 for i in range(0,len(nums)): if (target-nums[i]) in nums_set: #判斷是否nums[i]的補數在集合中 low=i for j in range(i+1,len(nums)): #上面判斷出了nums[i]的補數在集合中,需要查詢下標 if nums[j]+nums[i]==target: return [i,j]
C++程式碼如下: 宣告C++我沒有和python一樣用 集合 進行查詢是因為c++的set是基於紅黑樹的查詢方式,查詢的效率是O(logn)
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { unordered_map<int,int> d; int len=nums.size(); vector<int> res; for(int i=0;i<len;i++) { if(d.count(target-nums[i])) //判斷target-nums[i]是否在d的key值列表中 { res.push_back(d[target-nums[i]]); res.push_back(i); return res; } else { d[nums[i]]=i; } } } };
知識點總結:
(1). Python 的set型別和C++的unordered_map是由Hash對映實現的,查詢效率是O(n)。 C++的map和set是基於紅黑樹的,查詢速度是O(logn)。
(2).記住一個API:
ordered_map<int,int> d: //宣告一個無序對映
d[i]=j; //對i 鍵值賦值
d.count(i)!=0 d.find(i) != d.end() //在d的鍵值中查詢i是否存在