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