【LeetCode】015 3Sum

题目:

Given an array S of n integers, are there elements abc in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note: The solution set must not contain duplicate triplets.

For example, given array S = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

  

题解:

  对于i和j,在j+1至n中寻找符合条件的第三个值,一种方法是建立map映射表,利用map的find函数。对重复项的检测上使用了比较麻烦的方法。

Solution 1 (TLE)

 1 class Solution {
 2 public:
 3     vector<vector<int>> threeSum(vector<int>& nums) {
 4         vector<vector<int>> vv;
 5         vector<int> v;
 6         int i = 0, j = 0, n = nums.size(),tar=0;
 7         unordered_map<int, int> m;
 8         for(; i<n; i++)
 9         //value-position
10             m[nums[i]] = i;
11         for(i=0; i<n-2; i++) {
12             for(j=i+1; j<n-1; j++) {
13                  tar = 0 - nums[i] - nums[j];
14                 if(m.count(tar) && m[tar]>j) {
15                     v.push_back(nums[i]);
16                     v.push_back(nums[j]);
17                     v.push_back(tar);
18                     sort(v.begin(),v.end());
19                     if(find(vv.begin(),vv.end(),v) == vv.end())
20                         vv.push_back(v);
21                         v.clear();
22                 }
23             }
24         }
25         return vv;
26     }
27 };

  Solution 1 TLE的原因就在于重复字段的判断上,耗费了大量时间。那么怎么降低呢?这里有个小技巧,对于存在可重复数字的数组,往往联想到先将数组排序,这样可能会减少大量工作。于是在for循环前先将nums排序,然后在循环中对于两元素值相同的情况直接跳过,即当nums[i] == nums[i-1]时,由于nums[i-1]已经遍历完成,故跳过nums[i],对于j(尾指针)也是同样的处理。

Solution 2 (312ms)

class Solution {
public:
   vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> vv;
        vector<int> v;
        int i = 0, j = 0, n = nums.size(),tar=0;
        unordered_map<int, int> m;
        sort(nums.begin(),nums.end());

        for(; i<n; i++)
        //value-position
            m[nums[i]] = i;
        for(i=0; i<n-2; i++) {
            if (i>0 && nums[i-1]==nums[i]) continue;
            for(j=i+1; j<n-1; j++) {
                if (j>i+1 && nums[j-1]==nums[j]) continue;
                 tar = 0 - nums[i] - nums[j];
                if(m.find(tar) != m.end() && m[tar]>j) {
                    vv.push_back({nums[i],nums[j],tar});
                }
            }
        }
        return vv;
    }
};

  Solution 2 虽然AC了,但用时312ms,效率太低了。我们进一步进行优化。此题的思路就是在i之后的数组内寻找符合条件的两个值,Solution 1和Solution 2是将i和j固定,寻找第三个值,那么我们也可以固定i,寻找j和k来满足条件。还是先将数组排序,固定i后,j,k分别为剩余数组的头指针、尾指针,在j<k时执行搜索,直到j>=k时停止搜索。遇到重复项依然是跳过处理。

Solution 3  (119ms)

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

  在重复项检测上也可以利用set的特性:不包含重复项。这只是一个小技巧。

Solution 4 (279ms)

class Solution {
public:
    vector<vector<int> > threeSum(vector<int> &nums) {
        set<vector<int>> sv;
        sort(nums.begin(), nums.end());
        int n = nums.size();

        for(int i=0; i<n-2; i++) {
            if(nums[i] > 0) break;
            int a = nums[i];
            int j = i+1, k = n-1;
            while(j<k) {
                int b = nums[j], c = nums[k];
                if(a+b+c == 0) {
                    sv.push_back({a,b,c});
                    j++;
                    k--;
                }
                else if(a+b+c > 0) k--;
                else j++;
            }
        }
        return vector<vector<int>> (sv.begin(),sv.end());
    }
};
时间: 2024-11-05 08:05:17

【LeetCode】015 3Sum的相关文章

【LeetCode】16. 3Sum Closest

Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. For example, given array S = {-1 2

【LeetCode】 16. 3Sum Closest 解题小结

题目:Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. For example, given array S = {-1

【LeetCode】016 3Sum Closest

题目: Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. For example, given array S = {-

【leetcode】15. 3Sum

题目描述: Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. 解题分析: 这道题注意一下几点即可: 1,先固定前两个数的位置,移动第三个数,这样的查找方式不会有数字组合的遗漏: 2,要考虑到数组元素有重复的情况下的处理. 3,若先为数组排

【LeetCode】3Sum Closest 解题报告

[题目] Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. For example, given array S = {

【LeetCode】3Sum Closest 解题报告 (Java)

[题目] Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. For example, given array S = {

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