寫在前面:大家好!我是
ACfun
,我的暱稱來自兩個單詞Accepted
和fun
。我是一個熱愛ACM的蒟蒻。最近萌生了刷LeetCode的想法,所以我打算按照題號從LeetCode第一個題目開始做起,攻陷LeetCode。如果博客中有不足或者的錯誤的地方歡迎在評論區或者私信我指正,感謝大家的不吝賜教。我的唯一博客更新地址是:https://ac-fun.blog.csdn.net/。非常感謝大家的支持。一起加油,衝鴨!
用知識改變命運,用知識成就未來!加油 (ง •̀o•́)ง (ง •̀o•́)ง
原題鏈接:LeetCode 1.兩數之和
題目信息
題目描述
給定一個整數數組 nums 和一個目標值 target,請你在該數組中找出和爲目標值的那 兩個 整數,並返回他們的數組下標。
你可以假設每種輸入只會對應一個答案。但是,數組中同一個元素不能使用兩遍。
示例
給定 nums = [2, 7, 11, 15], target = 9
因爲 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
解題思路
暴力解題
思路
最簡單的思路就是暴力解題了,我們可以使用兩層for循環遍歷整數數組nums,直到遍歷完整個數組。先建立一個空的vector ans,如果有連個數 i 和 j,使得 i + j = target,那麼就將兩個數的下標添加到ans中並返回。如果遍歷完整個nums數組都找不到那麼就直接返回空的ans。
有關vector的使用可以看一下我之前的博客:C++STL之vector詳解
時間複雜度
因爲是使用的兩層for循環,所以該方法的時間複雜度爲:O(n^2)
解題代碼(C++)
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> ans;
int size = nums.size();
for(int i = 0;i < size-1;i++){
for(int j = i + 1;j < size;j++){
if(nums.at(i) + nums.at(j) == target){
ans.push_back(i);
ans.push_back(j);
return ans;
}
}
}
return ans;
}
};
提交情況
hashmap解法
思路
上一個思路雖然很容易就可以想到了,但是時間複雜度爲O(n^2)。比較高,時間複雜度再低一點我們可以使用C++中STL的map,map是一種有序無重複的關聯容器,底層實現是一個紅黑樹(一種嚴格意義上的平衡二叉樹),其查找的時間複雜度爲O(log(n))。使用map可以將時間複雜度從 O(n^2)降低到了O(nlog(n)),但是我們可以進一步的降低時間複雜度。我們可以使用C++中STL的unordered_map,unordered_map是一種無序的map,其底層實現爲哈希表,其查找的時間複雜度爲O(1)。
所以我們可以使用unordered_map來解這道題目,使用它我們又可以進一步的降低時間複雜度,將時間複雜度由O(nlog(n))降到了O(n)。
我們每次只尋找第二個數nums[i],那麼第一個數就爲aim = target - nums[i],在遍歷到nums[i]時如果我們建立的unordered_map中沒有aim,即 target - nums[i] != aim,那麼就將 nums[i] 作爲鍵(key),將 nums[i] 的下標作爲值存儲到unordered_map中,繼續循環遍歷,直到遍歷完整個nums。
時間複雜度
使用unordered_map解題的時間複雜度爲:O(n)。
解題代碼(c++)
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> hash;
int numsSize = nums.size();
for(int i = 0;i < numsSize;i++){
int aim = target - nums[i];
if(hash.count(aim)){
return {hash[aim],i};
}
hash[nums[i]] = i;
}
return {};
}
};
提交情況
未完待續,持續更新中……