【LeetCode】018 4Sum

题目:

Given an array S of n integers, are there elements abc, 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: The solution set must not contain duplicate quadruplets.

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]
]

题解:

  这个题与3Sum类似,求4Sum就在原基础上再加上一层循环就可以了。这里只给出此种解法思路的其中一个解法。

Solution 1 (36ms)

 1 class Solution {
 2 public:
 3     vector<vector<int>> fourSum(vector<int>& nums, int target) {
 4          set<vector<int>> sv;
 5          sort(nums.begin(), nums.end());
 6          int n = nums.size();
 7
 8          for(int i=0; i<n-3; i++) {
 9              for(int j=i+1; j<n-2; j++) {
10                  int k = j+1, l = n-1;
11                  int a = nums[i], b = nums[j];
12                  while(k<l) {
13                      int c = nums[k], d = nums[l];
14                      if(a+b+c+d == target) {
15                          sv.insert({a,b,c,d});
16                          k++;
17                          l--;
18                      }
19                      else if(a+b+c+d < target) k++;
20                      else l--;
21                  }
22              }
23          }
24          return vector<vector<int>> (sv.begin(),sv.end());
25     }
26 };

  还有一种解法,也是利用了3Sum,不过不是再加一层循环,而是直接调用3Sum函数:取nums[i],然后对后续剩余数组元素求3Sum,tar为target - nums[i];

Solution 2 (32ms)

 1 class Solution {
 2 public:
 3     vector<vector<int> > threeSum(vector<int> &nums, int target) {
 4         set<vector<int>> sv;
 5         sort(nums.begin(), nums.end());
 6         int n = nums.size();
 7
 8         for(int i=0; i<n-2; i++) {
 9             int a = nums[i];
10             int j = i+1, k = n-1;
11             while(j<k) {
12                 int b = nums[j], c = nums[k];
13                 if(a+b+c == target) {
14                     sv.insert({a,b,c});
15                     j++;
16                     k--;
17                 }
18                 else if(a+b+c > target) k--;
19                 else j++;
20             }
21         }
22         return vector<vector<int>> (sv.begin(),sv.end());
23     }
24      vector<vector<int>> fourSum(vector<int>& nums, int target) {
25          vector<vector<int>> vv;
26          sort(nums.begin(), nums.end());
27          int n = nums.size();
28
29          for(int i=0; i<n-3; i++) {
30              if(i>0 && nums[i] == nums[i-1]) continue;
31              //截取剩余数组
32              vector<int> v(nums.begin()+i+1,nums.end());
33              vector<vector<int>> tmp = threeSum(v, target - nums[i]);
34              for(int j=0; j<tmp.size(); j++) {
35                  tmp[j].insert(tmp[j].begin(), nums[i]);
36                  vv.push_back(tmp[j]);
37              }
38          }
39          return vv;
40     }
41 };

  还有一种更为优化的解法,思路是一致的,只是加了一个小技巧:在两个外循环中先判断四个值的和与target的大小,即

  if(nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target) break;
  if(nums[i]+nums[n-3]+nums[n-2]+nums[n-1]<target) continue;

  通过这两条语句减少了搜索时间,不必进入内循环判断;对于j同理。

Solution 3 (12ms)

 1 class Solution {
 2 public:
 3     vector<vector<int>> fourSum(vector<int>& nums, int target) {
 4          set<vector<int>> sv;
 5          sort(nums.begin(), nums.end());
 6          int n = nums.size();
 7          if(n<4)  return vector<vector<int>> (sv.begin(),sv.end());
 8          for(int i=0; i<n-3; i++) {
 9              if(nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target) break;
10              if(nums[i]+nums[n-3]+nums[n-2]+nums[n-1]<target) continue;
11              if(i>0&&nums[i]==nums[i-1]) continue;
12              for(int j=i+1; j<n-2; j++) {
13                  if(j>i+1&&nums[j]==nums[j-1]) continue;
14                 if(nums[i]+nums[j]+nums[j+1]+nums[j+2]>target) break;
15                 if(nums[i]+nums[j]+nums[n-2]+nums[n-1]<target) continue;
16                  int k = j+1, l = n-1;
17                  int a = nums[i], b = nums[j];
18                  while(k<l) {
19                      int c = nums[k], d = nums[l];
20                      if(a+b+c+d == target) {
21                          sv.insert({a,b,c,d});
22                          k++;
23                          l--;
24                      }
25                      else if(a+b+c+d < target) k++;
26                      else l--;
27                  }
28              }
29          }
30          return vector<vector<int>> (sv.begin(),sv.end());
31     }
32 };
时间: 2024-10-19 13:10:06

【LeetCode】018 4Sum的相关文章

【LeetCode】18. 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: The solution set must not contain duplicate quadruplets. For ex

【LeetCode】454 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 t

【leetcode】18. 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. 解题分析: 这个和3Sum那道题有些像,也是要先确定两个数,之后两个数的确定可以参考二分查找的实现方法进行优化. 具体代码: 1 pu

【leetcode】Generate Parentheses

题目: 给定整数n,返回n对匹配的小括号字符串数组. For example, given n = 3, a solution set is: "((()))", "(()())", "(())()", "()(())", "()()()" 分析: 这种问题的模式是:1)问题的解有多个 ,2)每个解都是由多个有效的 "步骤" 组成的,3)变更以有解的某个或某些"步骤"

【LeetCode】Implement strStr()

Implement strStr() Implement strStr(). Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack. 标准KMP算法.可参考下文. http://blog.csdn.net/yaochunnian/article/details/7059486 核心思想在于求出模式串前缀与后缀中重复部分,将重复信息保存在n

【LeetCode】Add Two Numbers

You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. Input: (2 -> 4 -> 3) + (5 -> 6 ->

【LeetCode】Pascal&#39;s Triangle

Pascal's Triangle Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5,Return [ [1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1] ] 这题别想用通项公式做,n choose m里面的连乘必然溢出,老老实实逐层用定义做. class Solution { public: vector<vector<

【LeetCode】Copy List with Random Pointer

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. Return a deep copy of the list. 思路:第一遍正常复制链表,同时用哈希表保存链表中原始节点和新节点的对应关系,第二遍遍历链表的时候,再复制随机域. 这是一种典型的空间换时间的做法,n个节点,需要大小为O(n

【leetcode】Max Points on a Line (python)

给定一个点,除该点之外的其他所有点中,与该点的关系要么是共线,要么就是共点,也就是两点重合. 共线有三种情况:水平共线,垂直共线,倾斜的共线.合并下这三种情况就是斜率存在的共线和斜率不存在的共线. 那么我们的任务就是针对每个点,找出与其共线的这些情况中,共线最多的点的个数. 注意:最终的结果别忘了加上共点的个数. class Solution: def maxPoints(self, points ): if len( points ) <= 1: return len( points ) ma