【LeetCode】015 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.
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)
 class Solution {
 public:
     vector<vector<int>> threeSum(vector<int>& nums) {
         vector<vector<int>> vv;
         vector<int> v;
         int i = , j = , n = nums.size(),tar=;
         unordered_map<int, int> m;
         for(; i<n; i++)
         //value-position
             m[nums[i]] = i;
         for(i=; i<n-; i++) {
             for(j=i+; j<n-; j++) {
                  tar =  - nums[i] - nums[j];
                 if(m.count(tar) && m[tar]>j) {
                     v.push_back(nums[i]);
                     v.push_back(nums[j]);
                     v.push_back(tar);
                     sort(v.begin(),v.end());
                     if(find(vv.begin(),vv.end(),v) == vv.end())
                         vv.push_back(v);
                         v.clear();
                 }
             }
         }
         return vv;
     }
 };
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 = , j = , n = nums.size(),tar=;
        unordered_map<int, int> m;
        sort(nums.begin(),nums.end());
        for(; i<n; i++)
        //value-position
            m[nums[i]] = i;
        for(i=; i<n-; i++) {
            if (i> && nums[i-]==nums[i]) continue;
            for(j=i+; j<n-; j++) {
                if (j>i+ && nums[j-]==nums[j]) continue;
                 tar =  - 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)
 class Solution {
 public:
     vector<vector<int> > threeSum(vector<int> &nums) {
         vector<vector<int>> vv;
         sort(nums.begin(), nums.end());
         int n = nums.size();
         for(int i=; i<n-; i++) {
             if(nums[i] > ) break;
             if(i> && nums[i] == nums[i-]) continue;
             int a = nums[i];
             int j = i+, k = n-;
             while(j<k) {
                 int b = nums[j], c = nums[k];
                 if(a+b+c == ) {
                     vv.push_back({a,b,c});
                     while(j<n && nums[j] == nums[j+]) j++; j++;
                     while(k>i && nums[k] == nums[k-]) k--; k--;
                 }
                 else if(a+b+c > ) {
                     while(k>i && nums[k] == nums[k-]) k--; k--;
                 }
                 else {
                     while(j<n && nums[j] == nums[j+]) j++; j++;
                 }
             }
         }
         return vv;
     }
 };
在重复项检测上也可以利用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=; i<n-; i++) {
            if(nums[i] > ) break;
            int a = nums[i];
            int j = i+, k = n-;
            while(j<k) {
                int b = nums[j], c = nums[k];
                if(a+b+c == ) {
                    sv.insert({a,b,c});
                    j++;
                    k--;
                }
                else if(a+b+c > ) k--;
                else j++;
            }
        }
        return vector<vector<int>> (sv.begin(),sv.end());
    }
};
【LeetCode】015 3Sum的更多相关文章
- 【LeetCode】15. 3Sum 三数之和
		作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 个人公众号:负雪明烛 本文关键词:3sum, 三数之和,题解,leetcode, 力扣,P ... 
- 【LeetCode】16. 3Sum Closest 最接近的三数之和
		作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 个人公众号:负雪明烛 本文关键词:3sum, three sum, 三数之和,题解,lee ... 
- 【LeetCode】923. 3Sum With Multiplicity 解题报告(Python)
		作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/3sum-wit ... 
- 【LeetCode】259 3Sum Smaller
		题目: Given an array of n integers nums and a target, find the number of index triplets i, j, k with 0 ... 
- 【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 ... 
- 【LeetCode】15. 3Sum 三个数和为0
		题目: Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find al ... 
- 【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 ... 
- 【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 ... 
- 【leetcode】923. 3Sum With Multiplicity
		题目如下: Given an integer array A, and an integer target, return the number of tuples i, j, k such tha ... 
随机推荐
- 几种动态调用js函数方案的性能比较
			<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ... 
- POJ 2965 The Pilots Brothers' refrigerator【枚举+dfs】
			题目:http://poj.org/problem?id=2965 来源:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=26732#pro ... 
- [转载]Java集合容器简介
			Java集合容器主要有以下几类: 1,内置容器:数组 2,list容器:Vetor,Stack,ArrayList,LinkedList, CopyOnWriteArrayList(1.5),Attr ... 
- 什么是gevent
			gevent是一个基于协程的python网络库,它使用greenlet在libev或libuv事件循环之上提供高级同步API 功能包括 基于libev或libuv的快速时间循环 基于greenlets ... 
- Data Structure Array: Move all zeroes to end of array
			http://www.geeksforgeeks.org/move-zeroes-end-array/ #include <iostream> #include <vector> ... 
- DevExpress实用心得:XtraGridControl动态添加右键菜
			在使用GridControl的时候经常需要添加右键菜单. 一般的做法是自己创建菜单项,然后注册GridView的Mouse-Click事件,然后Show出定义好的菜单. 但是涉及到一些单击事件会收到编 ... 
- 【leetcode刷题笔记】Reverse Integer
			Reverse digits of an integer. Example1: x = 123, return 321Example2: x = -123, return -321 解题:设定一个变量 ... 
- Linux 上通过rpm安装mysql
			安装mysql之前要remove掉系统自带的mysql: rpm -qa | grep "MySQL*" 和rpm -qa | grep mysql 要确保卸载干净 rpm ... 
- STL+位运算的文件
			1.queue 队列 queue的头文件是<queue>. 定义queue对象的示例代码如: queue<int>q; 队列内存放的是int类型的数 queue<dou ... 
- log4net性能小探
			初步测试了Log4性能.Appender架构如下. 一般客户端,使用FileAppender,把Log记录在本地磁盘. <lockingModel type="log4net.Appe ... 
