leetcode 1: twosum
阿新 • • 發佈:2018-12-12
題目描述:給出一個int陣列和一個int目標值,在陣列中找兩數之和等於target。假設肯定能找且每個數只能用一次。返回兩數在陣列的下標。
方法一:暴力求解
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { for(int i=0;i<nums.size();i++){ for(int j=i+1;j<nums.size();j++){ if(nums[i]+nums[j]==target) return vector<int>{i,j};//多借鑑這種返回vector的方法 } } return vector<int>{-1,-1}; } };
不足:時間複雜度是o()
優點:思路清晰、簡單
方法二:藉助 unordered_map
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { if(nums.size()<=1) return vector<int>{-1,-1}; unordered_map<int,int> hash; for(int i=0;i<nums.size();i++){ hash[nums[i]]=i; } for(int j=0;j<nums.size();j++){ if(hash.find(target-nums[j])!=hash.end() && hash[target-nums[j]]!=j){//每個元素只能用一次 return vector<int>{j,hash[target-nums[j]]}; } } return vector<int>{-1,-1}; } };
改進編碼版:
少了一層迴圈,不必先全部插入hash,而是一邊判斷,一邊插入。因為兩數和具有交換等效性,通過前面的數找不到,後面找也是等價的,並不會漏掉!
很值得借鑑!!!!!!!!!!!!!
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { if(nums.size()<=1) return vector<int>{-1,-1}; unordered_map<int, int> hash; for (int i = 0;i<nums.size(); ++i) { auto it = hash.find(target - nums[i]); if (it != hash.end()) return vector<int> {i, it->second}; //此處不擔心使用重複元素,因為判斷時元素還未插入 hash[nums[i]] = i; } return vector<int>{-1,-1}; } };
不足:前提要求陣列中沒有相同元素
優點:時間複雜度o(n)
拓展:先排序,兩個指標分別從兩端向中間收攏。但是隻能判斷能否the sum of 2 nums equals target,因為排序會打亂下標。