LeetCode # 3Sum #

来源:互联网 发布:测斜仪数据处理软件 编辑:程序博客网 时间:2024/06/05 03:34


 



Python解答一 O(n^3) 时间复杂度不符合要求, 暴力美还是很直观:


"""Programmer  :   EOFDate        :   2015.04.11File        :   3sum.pyE-mail      :   jasonleaster@gmail.comDescription :    This is the first version which I used and try to solve3Sum problem. It's work correctly but have a bad time complexity."""class Solution:    # @return a list of lists of length3, [[val1, val2, val3]]    ret_list = []    def threeSum(self, num):        length = len(num)        for i in range(0, length):            for j in range(i+1, length):                for k in range(j+1, length):                    if num[i] + num[j] + num[k] == 0:                                                tmp = self.sequence(num[i], num[j], num[k])                        if self.same_solution(tmp) is True:                            continue                        else:                            self.ret_list += [tmp]        return self.ret_list    # make sure that in @self.ret_list e1 < e2 < e3    def sequence(self, a, b, c):        ret = []        if a < b:            if a < c:                ret += [a]                if b < c:                    ret += [b, c]                else:                    ret += [c, b]            else:                ret += [c, a, b]        else: # a > b in this situation            if b < c:                ret += [b]                if a < c:                    ret += [a, c]                else:                    ret += [c, a]            else:                ret += [c, b, a]        return ret    def same_solution(self, sv):        if len(self.ret_list) != 0 :            row = len(self.ret_list)            col = len(self.ret_list[0])            for i in range(0, row):                for j in range(0, col):                    if self.ret_list[i][j] != sv[j]:                        break;                if j == col-1:                    return True        return False#------------- just for testing ----------s = Solution()Date = [-1, 0, 1, 2, -1, -4]print s.threeSum(Date)



解答二: 


我只想说...这已经是第四个版本了    (#‵′)

...

会发现代码短了很多, 但是这里还是过不了时间复杂度.

我用了两个hash表,

后面的ret_dic是为了避免出现重复的解答.


"""Programmer  :   EOFDate        :   2015.04.11File        :   3sum_opt_3.pyE-mail      :   jasonleaster@gmail.comDescription :    This is the #fourth# version which I used and try to solve3Sum problem. I used dictionary and try to improve the performance.It's work correctly but also have a bad time complexity."""class Solution:    # @return a list of lists of length3, [[val1, val2, val3]]    ret_list = []    dic  = {}    ret_dic  = {}    def threeSum(self, num):        length = len(num)        #   Initialize the @dic and @time        for i in range(0, length):            if num[i] not in self.dic:                self.dic[num[i]]  = num[i]        num.sort()        # Kernel part of this algorithm        for i in range(0, length):            for j in range(i + 1, length):                                #It's a old trick to use the inverse number as the index                if -(num[i] + num[j]) in self.dic:                                        if -(num[i] + num[j]) <= num[i] :                        tmp = [-(num[i] + num[j]), num[i], num[j] ]                    elif -(num[i] + num[j]) >= num[j] :                        tmp = [num[i], num[j], -(num[i] + num[j])]                    else:                        tmp = [num[i], -(num[i] + num[j]), num[j]]                    if str(tmp) not in self.ret_dic:                        self.ret_dic[str(tmp)] = tmp        for i in self.ret_dic:            self.ret_list += [self.ret_dic[i]]        return self.ret_list#------------- just for testing ----------s = Solution()Date = [-1, 0, 1, 2, -1, -4]print s.threeSum(Date)Date = [4,4,3,-5,0,0,0,-2,3,-5,-5,0]print s.threeSum(Date)


Python 解答三:

之前的两个解答都不能用的 ... 只有这个可以AC.

解答二可能由于构造dictionary的时候比较耗时, 所以时间复杂度有问题.


class Solution:    # @return a list of lists of length 3, [[val1,val2,val3]]    def threeSum(self, num):        if len(num) <= 2:            return []        ret = []        tar = 0        num.sort()        i = 0        while i < len(num) - 2:            j = i + 1            k = len(num) - 1            while j < k:                if num[i] + num[j] + num[k] < tar:                    j += 1                elif num[i] + num[j] + num[k] > tar:                    k -= 1                else:                    ret.append([num[i], num[j], num[k]])                    j += 1                    k -= 1                    # folowing 3 while can avoid the duplications                    while j < k and num[j] == num[j - 1]:                        j += 1                    while j < k and num[k] == num[k + 1]:                        k -= 1            while i < len(num) - 2 and num[i] == num[i + 1]:                i += 1            i += 1        return ret


凯旋冲锋的 Java 解答:


package _3sum;import java.util.Arrays;import java.util.LinkedList;import java.util.List;public class Solution {public List<List<Integer>> threeSum(int[] num) {Arrays.sort(num);List<List<Integer>> result = new LinkedList<>();for (int i = num.length - 1; i > 1; i--) {if (i + 1 < num.length && num[i] == num[i + 1]) {continue;}for (int j = 0, k = i - 1; j < k; ) {int sum = num[j] + num[k] + num[i];if (sum < 0) {j++;} else if (sum > 0) {k--;} else {result.add(Arrays.asList(num[j], num[k], num[i]));do {j++;k--;} while (j < k && num[j - 1] == num[j] && num[k] == num[k + 1]);}}}return result;}public static void main(String[] args) {System.out.println(new Solution().threeSum(new int[]{0, 0, 0, 0, 0, 0, 0}));}}



皓神的C++ 

Skip to content This repositoryExploreGistBlogHelp@jasonleaster jasonleaster  Unwatch 2  Star 0 Fork 920penguiner/leetcode-1forked from haoel/leetcode branch: master  leetcode-1/src/3Sum/3Sum.cpp@haoelhaoel on 31 Oct 2014 Add comments to explain the solutions1 contributorRawBlameHistory    188 lines (166 sloc)  5.134 kb// Source : https://oj.leetcode.com/problems/3sum/// Author : Hao Chen// Date   : 2014-07-22/********************************************************************************** * * 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:* * Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)* 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)* *               **********************************************************************************/#include <stdio.h>#include <iostream>#include <vector>#include <set>#include <algorithm>using namespace std;/* *   Simlar like "Two Number" problem, we can have the simlar solution. * *   Suppose the input array is S[0..n-1], 3SUM can be solved in O(n^2) time on average by  *   inserting each number S[i] into a hash table, and then for each index i and j,   *   checking whether the hash table contains the integer - (s[i]+s[j]) * *   Alternatively, the algorithm below first sorts the input array and then tests all  *   possible pairs in a careful order that avoids the need to binary search for the pairs  *   in the sorted list, achieving worst-case O(n^n) * *   Solution:  Quadratic algorithm *   http://en.wikipedia.org/wiki/3SUM * */vector<vector<int> > threeSum(vector<int> &num) {    vector< vector<int> > result;    //sort the array, this is the key    sort(num.begin(), num.end());    int n = num.size();    for (int i=0; i<n-2; i++) {        //skip the duplication        if (i>0 && num[i-1]==num[i]) continue;        int a = num[i];        int low = i+1;        int high = n-1;        while ( low < high ) {            int b = num[low];            int c = num[high];            if (a+b+c == 0) {                //got the soultion                vector<int> v;                v.push_back(a);                v.push_back(b);                v.push_back(c);                result.push_back(v);                // Continue search for all triplet combinations summing to zero.                //skip the duplication                while(low<n && num[low]==num[low+1]) low++;                 while(high>0 && num[high]==num[high-1]) high--;                 low++;                high--;            } else if (a+b+c > 0) {                //skip the duplication                while(high>0 && num[high]==num[high-1]) high--;                high--;            } else{                //skip the duplication                while(low<n && num[low]==num[low+1]) low++;                low++;            }         }    }    return result;}//using combination method could meet <<Time Limit Exceeded>> errorvector<vector<int> > combination(vector<int> &v, int k);bool isSumZero(vector<int>& v);int sum(vector<int>& v);vector<vector<int> > threeSum2(vector<int> &num) {    vector< vector<int> > result;    vector< vector<int> > r = combination(num, 3);    for (int i=0; i<r.size(); i++){        if (isSumZero(r[i])){            result.push_back(r[i]);        }    }    return result;}bool isSumZero(vector<int>& v){    return sum(v)==0;}int sum(vector<int>& v){    int s=0;    for(int i=0; i<v.size(); i++){        s += v[i];    }    return s;}vector<vector<int> > combination(vector<int> &v, int k) {    vector<vector<int> > result;    vector<int> d;    int n = v.size();    for (int i=0; i<n; i++){        d.push_back( (i<k) ? 1 : 0 );    }    //1) from the left, find the [1,0] pattern, change it to [0,1]    //2) move all of the 1 before the pattern to the most left side    //3) check all of 1 move to the right    while(1){        vector<int> tmp;        for(int x=0; x<n; x++){            if (d[x]) tmp.push_back(v[x]);        }        sort(tmp.begin(), tmp.end());        result.push_back(tmp);        //step 1), find [1,0] pattern        int i;        bool found = false;        int ones =0;        for(i=0; i<n-1; i++){            if (d[i]==1 && d[i+1]==0){                d[i]=0; d[i+1]=1;                found = true;                //step 2) move all of right 1 to the most left side                for (int j=0; j<i; j++){                    d[j]=( ones > 0 ) ? 1 : 0;                    ones--;                }                break;            }            if (d[i]==1) ones++;        }        if (!found){            break;        }    }    return result;}void printMatrix(vector<vector<int> > &matrix){    for(int i=0; i<matrix.size(); i++){        printf("{");        for(int j=0; j< matrix[i].size(); j++) {            printf("%3d ", matrix[i][j]) ;        }        printf("}\n");    }    cout << endl;}int main(){    //int a[] = {-1, 0, 1, 2, -1, 1, -4};    int a[] = {-1, 1, 1, 1, -1, -1, 0,0,0};    vector<int> n(a, a+sizeof(a)/sizeof(int));    vector< vector<int> > result = threeSum(n);    printMatrix(result);        return 0;}Status API Training Shop Blog About© 2015 GitHub, Inc. Terms Privacy Security Contact







0 0
原创粉丝点击