程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> LeetCode——4Sum & 總結

LeetCode——4Sum & 總結

編輯:C++入門知識

LeetCode——4Sum & 總結


 

前言

 

對於同類問題做了代碼模型:

int i = starting; //頭指針
int j = num.size() - 1; //尾指針
while(i < j) {
    int sum = num[i] + num[j];
    if(sum == target) {
        store num[i] and num[j] somewhere;
        if(we need only one such pair of numbers)
            break;
        otherwise
            do ++i, --j;
    }
    else if(sum < target)
        ++i;
    else
        --j;
}

題目

Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note:
• Elements in a quadruplet (a, b, c, d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
• Thesolutionsetmustnotcontainduplicatequadruplets.

For example, given array S = {1 0 -1 0 -2 2}, and target = 0.
A solution set is:
(-1, 0, 0, 1)
(-2, -1, 1, 2)
(-2, 0, 0, 2)

思路

關於這道有許多解法:

解法一:K Sum

// 先排序,然後左右夾逼,時間復雜度 O(n^3),空間復雜度 O(1) class Solution {
public:
      vector> fourSum(vector& num, int target) {
          vector> result;
          if (num.size() < 4) return result;
          sort(num.begin(), num.end());
          auto last = num.end();
          for (auto a = num.begin(); a < prev(last, 3); ++a) {
              for (auto b = next(a); b < prev(last, 2); ++b) {
                  auto c = next(b);
                  auto d = prev(last);
                  while (c < d) {
                      if (*a + *b + *c + *d < target) {
                          ++c;
?                      } else if (*a + *b + *c + *d > target) {
                          --d;
                      } else {
                          result.push_back({ *a, *b, *c, *d });
                          ++c;
                          --d;
} }
} }
          sort(result.begin(), result.end());
          result.erase(unique(result.begin(), result.end()), result.end());
          return result;
} };

補充: 關於unique()去重的使用,
 

解法二:Hashmap

用一個 hashmap 先緩存兩個數的和, 以及vector存這兩個數。
在用兩個游標遍歷序列,key = target -v[x]-v[y], 根據 map.find(key), 找出另外兩個數。

時間復雜度,平均 O(n^2),最壞 O(n^4),空間復雜度 O(n^2)

class Solution {
    public:
        vector > fourSum(vector &sums, int target) {
            vector > result;
            if (nums.size() < 4) return result;
            sort(nums.begin(), num.end());

            unordered_map > > cache;
            for (int i=0; i(i, j));
                }
            }

            for (int x=0; x > vec = cache[key];
                    for (int k=0; k

解法三:Multimap

首先要說的是 multimap的概念。

multimap提供了可以一種可以有重復鍵值的STL map類型。其插入方式和map相似,但是由於可以擁有重復鍵值所以在查找方面有些不同

直接找到每種鍵值的所有元素的第一個元素的游標

通過函數:lower_bound( const keytype& x ), upper_bound( const keytype& x ) 可以找到比指定鍵值x的小的鍵值的第一個元素和比指定鍵值x大的鍵值的第一個元素。返回值為該元素的游標。

細節:當到達鍵值x已經是最大時,upper_bound返回的是這個multimap的end游標。同理,當鍵值x已經是最小了,lower_bound返回的是這個multimap的begin游標。

指定某個鍵值,進行遍歷

可以使用上面的lower_bound和upper_bound函數進行游歷,也可以使用函數equal_range。其返回的是一個游標對。游標對pair::first是由函數lower_bound得到的x的前一個值,游標對pair::second的值是由函數upper_bound得到的x的後一個值。


這個算法的 時間復雜度 O(n^2),空間復雜度 O(n^2)

#include 
#include 
#include 

using namespace std;

class Solution {
    public:
        vector > fourSum(vector& num, int target) {
            vector > result;
            if (num.size()<4) return result;
            sort(num.begin(), num.end());

            unordered_multimap> cache;
            for (int i=0; i+1first;
                pair range = cache.equal_range(x);
                for (pair j = range.first; j!=range.second; ++j) {
                    int a = i->second.first;
                    int b = i->second.second;
                    int c = j->second.first;
                    int d = j->second.second;
                    if (a != c && a != d && b != c && b != d) {
                                                                vector vec = { num[a], num[b], num[c], num[d] };
                                                                sort(vec.begin(), vec.end());
                                                                result.push_back(vec);
                    }
                }
            }
            sort(result.begin(), result.end());
            result.erase(unique(result.begin(), result.end()), result.end());
            return result;
        }
};

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved