标签:
Python解答一 O(n^3) 时间复杂度不符合要求, 暴力美还是很直观:
""" Programmer : EOF Date : 2015.04.11 File : 3sum.py E-mail : jasonleaster@gmail.com Description : This is the first version which I used and try to solve 3Sum 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 : EOF Date : 2015.04.11 File : 3sum_opt_3.py E-mail : jasonleaster@gmail.com Description : This is the #fourth# version which I used and try to solve 3Sum 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 repository Explore Gist Blog Help @jasonleaster jasonleaster Unwatch 2 Star 0 Fork 920penguiner/leetcode-1 forked from haoel/leetcode branch: master leetcode-1/src/3Sum/3Sum.cpp @haoelhaoel on 31 Oct 2014 Add comments to explain the solutions 1 contributor RawBlameHistory 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>> error vector<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
标签:
原文地址:http://blog.csdn.net/cinmyheart/article/details/45010033