1. 程式人生 > >查詢表,Two Sum,15. 3Sum,18. 4Sum

查詢表,Two Sum,15. 3Sum,18. 4Sum

解法一:排序後使用雙索引對撞:O(nlogn)+O(n) = O(nlogn) , 但是返回的是排序前的指標。

解法二:查詢表。將所有元素放入查詢表, 之後對於每一個元素a,查詢 target-a 是否存在。使用map實現,鍵是元素的值,鍵值是元素對應的索引。

不能把vector中所有的值放到查詢表中,因為若有重複的值,前一個會被後一個覆蓋。所以改善為把當前元素v前面的元素放到查詢表中。

時間複雜度:O(n)

空間複雜度:O(n)

 

class Solution {
public:
    vector<int> twoSum(vector<int
>& nums, int target) { unordered_map<int, int> record; for(int i=0; i<nums.size();i++){ int complement = target - nums[i]; if(record.find(complement) != record.end()){ int res[2] = {i, record[complement]}; //res記錄兩個元素的索引 return
vector<int>(res, res+2); } record[nums[i]] = i; } throw invalid_argument("The input has no solution"); } };

需要考慮不同的三元組:是要求值不同還是索引不同。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector
<vector<int> > res; if(nums.size()<=2){ return res; } sort(nums.begin(), nums.end()); size_t i = 0; while(i<nums.size()-2){ int target = -nums[i]; int l = i+1; int r = nums.size()-1; while(l<r){ int sum = nums[l]+nums[r]; if(sum<target) l++; else if(sum>target) r--; else{ vector<int> triplet = {nums[i], nums[l], nums[r]}; res.push_back(triplet); //避免把重複的一組數字存入res中 while(l<r && nums[l] == triplet[1]) l++; while(l<r && nums[r] == triplet[2]) r--; } } int curNum = nums[i]; while(i<nums.size()-2 && nums[i]==curNum) i++; } return res; } };