编程之美之高速寻找多个数满足给定条件

slgkaifa slgkaifa     2022-08-28     157

关键词:

一、寻找三个数之和等于给定值

分析:方法类似与2Sum。就是先对数组进行排序,时间复杂度为O(nlogn),然后固定一个数,用两个指针进行遍历,找到三个数之和等于给定的值就可以,时间复杂度为O(n^2)。详细可提交于leetcode:https://oj.leetcode.com/problems/3sum/,代码例如以下:

vector<vector<int> > threeSum(vector<int> &num,int target){
	vector<vector<int> >res;
	int i,j,k,size = num.size();
	sort(num.begin(),num.end());
	for(i=0;i<size;i++)//固定一个数
	{
		if(i>0 && num[i] == num[i-1])continue;//防止反复计算,比如1 1 -1 0,target=0,假设没有该推断,结果会有两个 1 -1 0
		j = i + 1;//循环遍历另外两个指针
		k = size-1;
		while(j < k)
		{
			if(num[i]+num[j]+num[k] == target)
			{
				vector<int> tmp;
				tmp.push_back(num[i]);
				tmp.push_back(num[j]);
				tmp.push_back(num[k]);
				res.push_back(tmp);
				j++;
				k--;
				while(num[j] == num[j-1])j++;
				while(num[k] == num[k+1])k++;
			}
			if(num[i]+num[j]+num[k] > target)k--;
			else j++;
		}
	}
	return res;
}
二、寻找三个数之和最接近给定值

分析:要找出的三个数可能不是恰好等于目标值。方法类似于上面的分析,仅仅是在每次三个数之和推断时。当三个数之和小于等于或大于等于给定target时,不光要移动指针,还要还当前最接近的和比較。留下最接近的和。题目见leetcode:3Sum Closet,代码例如以下:

bool flag = true;//用于第一次记录最接近的三个数之和
int threeSumClosest(vector<int> &num, int target)
{
	sort(num.begin(),num.end());
	int i,j,k,currentSum=0,size = num.size();
	for(i=0;i<size;i++)
	{
		if(j>0 && num[j] == num[j-1])continue;
		j = i+1;
		k = size -1;
		while(j < k)
		{
			if(abs(num[i]+num[j]+num[k]-target)<abs(currentSum-target) || flag)
			{
				currentSum = num[i]+num[j]+num[k];//替换最接近的三个数
			}
			flag = false;
			if(abs(num[i]+num[j]+num[k]) < target)
			{
				j++;
				while(num[j] == num[j-1])j++;
			}
			else
			{
				k--;
				while(num[k] == num[k+1])k--;
			}
		}
	}
	return currentSum;
}

三、寻找四个数之和等于给定值

方法和三个数的和一样,仅仅是多了一层循环,据说有更快的方法。能力有限,没写出来,希望高手指点。见leetcode上4Sum,代码例如以下:

vector<vector<int> > fourSum(vector<int> &num, int target)
{
	sort(num.begin(),num.end());
	vector<vector<int> > res;
	int i,j,k,t,size = num.size();
	for(i=0;i<size-3;i++)
	{
		if(i>0 && num[i]==num[i-1])continue;
		for(j=i+1;j<size-2;j++)
		{
			if(j> i+1 && num[j] == num[j-1])continue;
			k = j+1;
			t = size-1;
			while(k < t)
			{
				if(num[i] + num[j] + num[k] + num[t] == target)
				{
					vector<int> tmp;
					tmp.push_back(num[i]);
					tmp.push_back(num[j]);
					tmp.push_back(num[k]);
					tmp.push_back(num[t]);
					res.push_back(tmp);
					k++;
					t--;
					while(k < t && num[k] == num[k-1])k++;
					while(k < t && num[t] == num[t+1])t--;
				}
				else if(num[i] + num[j] + num[k] + num[t] > target) t--;
				else k++;
			}
		}
	}
	return res;
}

四、寻找随意个和等于给定值

分析:因为能够是随意个数,所以使用递归比較方便,简单的说就是顺序遍历每个数。类似于背包问题。取的话结果有哪些,不取的话结果有哪些,从而得出全部的结果,不知道还有没有高效的算法,代码例如以下:

void anySum(vector<int> numbers,int target,int index,vector<int>& currSum,vector<vector<int> >& res)
{
	if(index > numbers.size())return;
	if(target == 0)
	{
		res.push_back(currSum);//获得一个结果
		return;
	}
	currSum.push_back( numbers[index]);//本次取该数进行递归
	target -= numbers[index];
	anySum(numbers,target,index+1,currSum,res);
	currSum.pop_back();//本次不取该数进行递归
	target += numbers[index];
	anySum(numbers,target,index+1,currSum,res);
}
vector<vector<int> > anySum(vector<int> numbers,int target)
{
	vector<vector<int> > res;
	vector<int> currSum;
	anySum(numbers,target,0,currSum,res);
	return res;
}

以上列出了若干数求和的几种情况,也算是自己的一个总结,有错误的地方,还请指正,谢谢

编程之美之2.5寻找最大的k个数

【题目】有很多无序的数,从中找出最大的K个数。假定他们都不相等。【解法一】如果数据不是很多,例如在几千个左右,我们可以排一下序,从中找出最大的K个数。排序可以选择快速排序或者堆排序[cpp] viewpla... 查看详情

编程之美-1的个数

1的数目题目:给定一个十进制正整数N,写下从1开始,到N的所有整数,然后数一下其中出现所有“1”的个数。例如:N=2,写下1~2。这样只出现了1个“1”。N=12,我们会写下1,2,3,4,5,6,7,8,9,10,11,12,这样,1的个数是5。问题是:1.写一... 查看详情

编程之法:面试和算法心得(寻找和为定值的多个数)

内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java题目描述输入两个整数n和sum,从数列1,2,3.......n中随意取几个数,使其和等于sum,要求将其中所有的可能组合列出来。分析与解法解法一注意到取n,... 查看详情

找到满足给定条件的排列

...017-02-1713:45:24【问题描述】:我想找出nnumber的所有排列的个数。编号将从1到n。给定条件是每个ithposition最多可以有Si的编号,其中Si是为数字的每个位置提供的。1<=n<=10^61<=si<=n例如:n=5那么它的所有五个元素将是1 查看详情

多线程编程-设计模式之保护性暂挂(guardedsuspesion)模式

GuardedSuspension模式的架构核心是一个受保护方法(GuardedMethod).该方法需要执行其所要真正执行的操作时需要满足特定的条件(Predicate,以下称之为保护条件)。当该条件不满足时,执行受保护方法的线程会被挂起进入等待状态... 查看详情

1777:寻找整数(代码片段)

1777:寻找整数时间限制:1000ms        内存限制:262144KB【题目描述】给定整数m,k,求出正整数n使得n+1,n+2,…,2n中恰好有m个数在二进制下恰好有k个1。有多组数据。【输入】第一行一个整数t表示数据... 查看详情

求数组满足条件个数

1问题给定一个数组,求出满足条件的数字个数。2方法(1)使用main()函数,打出数组。(2)用循环遍历然后if判断做出统计(3)输出结果。publicclasstext07publicstaticvoidmain(String[]args)int[]a=20,45,78,34,16,3,99,56;第一步:将数组打印i... 查看详情

求数组满足条件个数

1问题给定一个数组,求出满足条件的数字个数。2方法(1)使用main()函数,打出数组。(2)用循环遍历然后if判断做出统计(3)输出结果。publicclasstext07publicstaticvoidmain(String[]args)int[]a=20,45,78,34,16,3,99,56;第一步:将数组打印i... 查看详情

编程之美_集合

时间限制:12000ms单点时限:6000ms内存限制:256MB描写叙述统计满足下列条件的集合对(A,B)的数量:A,B都是{1,2,…,N}的子集;A,B没有公共的元素;f(A)<=f(B)。f(S)定义为S中全部元素的按位异或和。比如, f({})=0,f({1,3})=2。由于答案可... 查看详情

《编程之美》——寻找发帖“水王”学习与扩展

问题描述(难度*):传说,Tango有一大“水王”,他不但喜欢发贴,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子总数的一半。如果你有一个当前论坛上所有帖子(包括回帖)的列表,其中帖子作者的I... 查看详情

百度2017春招笔试真题编程题集合之寻找三角形

题目描述三维空间中有N个点,每个点可能是三种颜色的其中之一,三种颜色分别是红绿蓝,分别用‘R‘,‘G‘,‘B‘表示。现在要找出三个点,并组成一个三角形,使得这个三角形的面积最大。但是三角形必须满足:三个点的颜... 查看详情

hdu-6084寻找母串

对于一个串S,当它同时满足如下条件时,它就是一个01偏串:1、只由0和1两种符组成;2、在S的每一个前缀中,0的个数不超过1的个数;3、S中0的个数和1的个数相等。现在给定01偏串S,请计算一下S在所有长度为n的01偏串中作为子... 查看详情

javascript面向对象编程高速构建继承关系之整合原型链

前面我们铺垫了非常多细节。是为了让大家更加明晰prototype的使用细节;如今能够将前面的知识整合起来,写一个函数用于高速构建基于原型链的继承关系了:functionextend(Child,Parent){ varF=function(){}; F.prototype=Parent.prototype; Child.proto... 查看详情

编程之美初赛第一场

题目3:活动中心时间限制:12000ms单点时限:6000ms内存限制:256MB描写叙述A市是一个高度规划的城市。可是科技高端发达的地方,居民们也不能忘记运动和锻炼,因此城市规划局在设计A市的时候也要考虑为居民们建造一个活动中心。... 查看详情

《编程之美》“1的数目”的另一个解法(代码片段)

问题:给定一个十进制正整数N,写下从1开始,到N的所有整数,然后数一下其中出现的所有“1”的个数。书上给的最优解,考虑十进制表示的每一位,对于0,1,其他这三种情况分开讨论,然后结合高位数字、当前位数字... 查看详情

编程之美----字符串移位包含的问题(代码片段)

...符串包含的判断,从而遍历其所有可能性。(程序参考《编程之美》)  解法二:    对解法一分析,可知,对s1循环所得的字符串都是字符串s1s1的 查看详情

java并发编程之美之并发编程线程基础(代码片段)

什么是线程  进程是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,线程则是进程的一个执行路径,一个进程至少有一个线程,进程的多个线程共享进程的资源。  java启动main函数其实就是启动... 查看详情

编程之美之让cpu占用率听你指挥

昨天在bbs上淘到了这本编程之美。顺手刷了第一章,很有意思。第一章的要求是要控制CPU曲线,绘制出对应的形状。拿到这个问题,我的第一反应是,是不是有这么一个API,能在任务管理器上的对应区域直接绘制图形呢?然后就... 查看详情