LeetCode——4Sum & 总结

LeetCode——4Sum & 总结

前言

有人对 Leetcode 上 2Sum,3Sum,4Sum,K Sum问题作了总结:

http://blog.csdn.net/nanjunxiao/article/details/12524405

对于同类问题做了代码模型:

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<vector<int>> fourSum(vector<int>& num, int target) {
          vector<vector<int>> 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()去重的使用,

參考 http://blog.csdn.net/zlhy_/article/details/8784553

解法二:Hashmap

用一个 hashmap 先缓存两个数的和, 以及vector<int, int>存这两个数。

在用两个游标遍历序列。key = target -v[x]-v[y], 依据 map.find(key), 找出另外两个数。

时间复杂度,平均 O(n^2),最坏 O(n^4),空间复杂度 O(n^2)

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

            unordered_map<int, vector<pair<int, int> > > cache;
            for (int i=0; i<nums.size(); ++i) {
                for (int j=i+1; j<nums.size(); ++j){
                    cache[nums[i]+num[j]].push_back(pair<int, int>(i, j));
                }
            }

            for (int x=0; x<nums.size(); ++x) {
                for (int y=x+1; y<nums.size(); ++y) {
                    int key = target - nums[x] - nums[y];
                    if (cache.find(key) == cache.end()) continue;

                    vector<pair<int, int> > vec = cache[key];
                    for (int k=0; k<vec.size(); ++k) {
                        if (x <= vec[k].second)
                            continue; //有重叠
                        result.push_back({ nums[vec[k].first], nums[vec[k].second], nums[c], nums[d]});
                    }
                }
            }
            sort(result.begin(), result.end());
            result.erase(unique(result.begin(), result.end()), result.end());
            return result;
        }
};

解法三:Multimap

首先要说的是 multimap的概念。

multimap提供了能够一种能够有反复键值的STL map类型。其插入方式和map类似,可是因为能够拥有反复键值所以在查找方面有些不同

  1. 直接找到每种键值的全部元素的第一个元素的游标

通过函数:lower_bound( const keytype& x ), upper_bound( const keytype& x ) 能够找到比指定键值x的小的键值的第一个元素和比指定键值x大的键值的第一个元素。返回值为该元素的游标。

细节:当到达键值x已经是最大时。upper_bound返回的是这个multimap的end游标。同理,当键值x已经是最小了,lower_bound返回的是这个multimap的begin游标。

  1. 指定某个键值,进行遍历

能够使用上面的lower_bound和upper_bound函数进行游历。也能够使用函数equal_range。其返回的是一个游标对。游标对pair::first是由函数lower_bound得到的x的前一个值,游标对pair::second的值是由函数upper_bound得到的x的后一个值。



这个算法的 时间复杂度 O(n^2),空间复杂度 O(n^2)

#include <iostream>
#include <vector>
#include <unordered_multimap>

using namespace std;

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

            unordered_multimap<int, pair<int, int>> cache;
            for (int i=0; i+1<num.size(); ++i) {
                for (int j=i+1; j<num.size(); ++j){
                    cache.insert(make_pair(num[i]+num[j], make_pair(i, j)));
                }
            }

            for (pair i =cache.begin(); i!=cache.end(); ++i){
                int x = target - a->first;
                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<int> 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;
        }
};
时间: 2024-10-29 19:05:42

LeetCode——4Sum &amp; 总结的相关文章

[Leetcode] 4Sum

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.

[leetcode]4Sum @ Python

原题地址:http://oj.leetcode.com/problems/4sum/ 题意:从数组中找到4个数,使它们的和为target.要求去重,可能有多组解,需要都找出来. 解题思路:一开始想要像3Sum那样去解题,时间复杂度为O(N^3),可无论怎么写都是Time Limited Exceeded.而同样的算法使用C++是可以通过的.说明Python的执行速度比C++慢很多.还说明了一点,大概出题人的意思不是要让我们去像3Sum那样去解题,否则这道题就出的没有意义了.这里参考了kitt的解

LeetCode——4Sum &amp; 总结

LeetCode--4Sum & 总结 前言 有人对 Leetcode 上 2Sum,3Sum,4Sum,K Sum问题作了总结: http://blog.csdn.net/nanjunxiao/article/details/12524405 对于同类问题做了代码模型: int i = starting; //头指针 int j = num.size() - 1; //尾指针 while(i < j) { int sum = num[i] + num[j]; if(sum == targe

LeetCode——4Sum

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.

[LeetCode] 4Sum 四数之和

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.

LeetCode 4Sum 4个数之和

题意:这是继2sum和3sum之后的4sum,同理,也是找到所有4个元素序列,满足他们之和为target.以vector<vector<int>>来返回,也就是二维的,列长为4,有多少个序列就多少行,每行都是唯一的,且升序. 思路: 方法一:用类似3sum的方法,先确定下第1个元素,再确定第2个元素,剩下两个元素用“两个指针”.前提是已排序.这个方法主要是怎么去重,这里提供两种方法: 1)用unordered_set,只要找到一个序列就检查里面有没有这样的序列,若没有就插入,这样保

[LeetCode] 4Sum hash表

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.

Leetcode: 4Sum II

Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero. To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. All integers are in the r

Solution to LeetCode Problem Set

Here is my collection of solutions to leetcode problems. LeetCode - Course Schedule LeetCode - Reverse Linked List LeetCode - Isomorphic Strings LeetCode - Count Primes LeetCode - Remove Linked List Elements LeetCode - Happy Number LeetCode - Bitwise