`

K Sum

 
阅读更多

2sum的算法复杂度是O(N log N) 因为排序用了N log N以及头尾指针的搜索是线性的,所以总体是O(N log N),好了现在考虑3sum, 有了2sum其实3sum就不难了,这样想:先取出一个数,那么我只要在剩下的数字里面找到两个数字使得他们的和等于(target – 那个取出的数)就可以了吧。所以3sum就退化成了2sum, 取出一个数字,这样的数字有N个,所以3sum的算法复杂度就是O(N^2 ), 注意这里复杂度是N平方,因为你排序只需要排一次,后面的工作都是取出一个数字,然后找剩下的两个数字,找两个数字是2sum用头尾指针线性扫,这里很容易错误的将复杂度算成O(N^2 log N),这个是不对的。我们继续的话4sum也就可以退化成3sum问题(copyright @sigmainfy),那么以此类推,K-sum一步一步退化,最后也就是解决一个2sum的问题,K sum的复杂度是O(n^(K-1))。 这个界好像是最好的界了,也就是K-sum问题最好也就能做到O(n^(K-1))复杂度,之前有看到过有人说可以严格数学证明,这里就不深入研究了。

 

class Solution {
public:
	vector< vector > findZeroSumInSortedArr(vector &num, int begin, int count, int target) {
		vector<vector > ret;
		vector tuple;
		set visited;
		if (count == 2) {
			int i = begin, j = num.size()-1;
			while (i < j) {
				int sum = num[i] + num[j];
				if (sum == target && visited.find(num[i]) == visited.end()) {
					tuple.clear();
					visited.insert(num[i]);
					visited.insert(num[j]);
					tuple.push_back(num[i]);
					tuple.push_back(num[j]);
					ret.push_back(tuple);
					i++; j–;
				} else if (sum < target) {
					i++;
				} else {
					j–;
				}
			}
		} else {
			for (int i=begin; i<num.size(); i++) {
				if (visited.find(num[i]) == visited.end()) {
					visited.insert(num[i]);
					vector subRet = findZeroSumInSortedArr(num, i+1, count-1, target-num[i]);
					if (!subRet.empty()) {
						for (int j=0; j<subRet.size(); j++) {
							subRet[j].insert(subRet[j].begin(), num[i]);
						}
						ret.insert(ret.end(), subRet.begin(), subRet.end());
					}
				}
			}
		}
		return ret;
	}

	vector threeSum(vector &num) {
		sort(num.begin(), num.end());
		return findZeroSumInSortedArr(num, 0, 3, 0);
	}

	vector fourSum(vector &num, int target) {
		sort(num.begin(), num.end());
		return findZeroSumInSortedArr(num, 0, 4, target);
	}
};

From:

http://tech-wonderland.net/blog/summary-of-ksum-problems.html

分享到:
评论

相关推荐

    神经进化游戏实验。-JavaScript开发

    一个神经进化游戏实验“瞄准并射击你是Nole Ksum”(k是沉默的),一个市民对机器起义的担忧,他决定将事情交到自己手中,并结束所有人工智能。 您必须杀死所有由神经网络控制的邪恶机器人,并阻止它们演变成更危险...

    leetcode打不开-leetcode:leetcode

    Sum) Tip2: Sum[i:j] = Sum[0:j] - Sum[0:i] for continuous array (# Array 560. Subarray Sum Equals K) Tip3: Knapsack Problem (0/1, unbounded) (#DP 322. Coin Change) Tip4: backtrace or K sum remove ...

    Max Sum Plus Plus(ACM ,c语言)

    int main() { int i,j,m,n,t,p,q,k; while(scanf("%d %d",&m,&n)==2) { for(k=0;k;k++) { scanf("%d",&a[k]); }

    pynq-z1_c_SUM_matlab_

    % ------ Vertical step ------ for j = 1:N % Find non-zero in the... for k = 1:length(r1) % Update L(qij) by summation of L(rij)\r1(k) Lqij(r1(k) j) = Lci(j) + sum(Lrji(r1 j)) - Lrji(r1(k) j); end % for k

    动态规划-Subarray Sum Equals K-子数组和为K

    给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的子数组。如果存在该子数组返回true,否则返回false。 #include #include using namespace std; int main() { std::cout &lt;...

    判断链表是否为回文链表leetcode-leetcode-[removed]使用javascript编写leetcode

    Sum 0001-Two Sum 0167-Two Sum II - 数组已经有序 1099-比 K 小的两数之和 0015-三数之和 对于两数之和,为了达到达到线性复杂度可以考虑使用 map 来保存遍历过程中的信息,在数组已经有序的情况下,可以通过首尾双...

    Shannon_SUM_C++_

    Shannon编码步骤: 1、将信源符号按概率从大到小的顺序排列,  p... 1-log2 p(ai) 3、令P(a1)=0,用Pi表示第i个码字的累加概率, Pi=sum_{k=1}^{i-1} p(ak) 4、将Pi用二进制表示并取小数点后Ki位作为符号ai的编码。

    leetcode答案-Leetcode:力码

    leetcode 答案 Leetcode Leetcode test 11 Container With Most Water 这里题目的分析图如下: 所以我们需要找的是ai,aj中的最小值作为高,然后找(i-j)的最大值作为长 ...用两个point来记录现在所在的x...FourSum...KSum

    Python+K邻近

    sqDistances = sqDiffMat.sum(axis=1) distances = sqDistances**0.5 sortedDistIndicies = distances.argsort() classCount={} for i in range(k): voteIlabel = labels[sortedDistIndicies[i]] ...

    Representations of an integer as sum of a primitive root and a $k$-th residue

    表整数为一个原根及$k$阶余项的和,徐哲峰,,令 $pge3$为素数, $n, k$为整数并满足$1leqn, kleq p-1$. 本文主要研究$N_k(n, p)$的渐近性质, 表整数$n$为一个原根及$k$阶模$p$余项的和的个数, 以�

    关于k-sum-avoiding子集基数的估计 (2014年)

    对sum-avoiding子集进行推广,对任意正整数k(k≥2),若集合S是A∈N的一个子集,且S中任意k个元素的和都不属于A,则S称为集合A的k-sum-avoiding子集.估计了当|A|=n时,A的k-sum-avoiding子集S的最大基数.

    c语言程序源代码

    int i,t,K,sum; for(i=2;i;i++) {sum=0; for(t=1;t;t++) if(i%t==0) sum=sum+t; if(sum==i) { printf("%d factors are ",i); for(K=1;K;K++) if(i%K==0) printf("%d\n",K); } } }

    C++(代码大全)三百例.

    #include class K { public: K(int i) { k=i;} int setk() const { return k;} private: int k;... int add(const K& g1,const K& g2);... K k1(8),k2(17);... int sum=g1.setk()+g2.setk(); return sum; }

    计算器代码

    Public sum As Double Public k As String "定义全局变量 Private Sub Command1_Click(Index As Integer) Select Case Index Case 1 Text1.Text = Text1.Text & 1 Case 2 Text1.Text = Text1.Text & 2 Case 3 Text1....

    常用计算器及变压器直流电阻计算

    Public sum As Double Public k As String Private Sub Command1_Click(Index As Integer) Select Case Index Case 1 Text1.Text = Text1.Text & 1 Case 2 Text1.Text = Text1.Text & 2 Case 3 Text1.Text = Text1....

    退火算法 解TSP

    E 就是求距离之和,这里是能量函数 // double E(const vector&lt;int&gt;& K,int N) ... sum+=sqrt((X[K[i]]-X[K[(i+1)%N]])*(X[K[i]]-X[K[(i+1)%N]]) +(Y[K[i]]-Y[K[(i+1)%N]])*(Y[K[i]]-Y[K[(i+1)%N]])); return sum; }

    MATLAB实现K-means聚类

    function [idx, C, sumD, D] = kmeans(X, k, varargin) % varargin:实际输入参量 if nargin error('At least two input arguments required.'); end % n points in p dimensional space [n, p] = size(X); ...

    基于类间差异最大化的加权距离改进K-means算法 (2010年)

    为了改善K-means算法的聚类效果,将聚类准则函数定义为加权的类内误差平方总和SSE(sum of thesquared error),并调整了K-means算法迭代过程中重新分配数据对象的方法:使用一个带有类内数据对象数的加权距离作为...

    c语言 高斯滤波 图片处理

    c语言 高斯滤波 if(i+k ){i+k=abs(i+k)-1;} if(i+k &gt; y_size2-1){i+k = 2*y_size2-i-k-1;} if(j+l ){j+l=abs(j+l)-1;} if(j+l &gt; x_size2-1){j+l = 2*x_size2-... sum1 +=t*d[i+k][j+l]; sum2 += t;

Global site tag (gtag.js) - Google Analytics