面试题:检查一个数组里是否存在m个数的和等于某个值

检查一个数组里是否存在m个数的和等于某个值

个人信息:就读于燕大本科软件工程专业 目前大三;

本人博客:google搜索“cqs_2012”即可;

个人爱好:酷爱数据结构和算法,希望将来从事算法工作为人民作出自己的贡献;

编程语言:C++ ;

编程坏境:Windows 7 专业版 x64;

编程工具:vs2008;

制图工具:office 2010 powerpoint;

硬件信息:7G-3 笔记本;


真言

别人吃不了的苦,我能吃;别人受不了的罪,我能受;别人觉得委屈了,我没有;不求别的,只求自己比别人更坚强,对得起父母给自己起的名字。

题目

检查一个数组里是否存在m个数的和等于某个值

方案

此题前面有一个题目,检查数组里是否存在两个数的和等于某个值

这个题目的解法

1)先给数组排序,时间复杂度为排序的时间复杂度(根据自己选择的排序方法而定)

2)  双向遍历:数组里最大值与最小值的和 sum  与 给定值 k 的 关系 ,时间复杂度为O(n )

while( 最小值 < 最大值 )

{

if( sum == k)

return true;

else if(sum < k)

{

舍弃最小值,更新最小值:取比最小值大的最小值

}

else  舍弃最大值,更新最大值: 取比最大值小的最大值

}

3)C++ 表示算法如下,这里我使用的是计数排序


// 求出两个数之和为定值的两个数
	std::pair Array::SumKOfTwo(int * data,unsigned int const length,int sum)
	{
		// 异常输入
			if(data == NULL || length == 0)
			{
				cout<<"error input of SumK,data = "<

问题扩展:是否存在多个数的和等于某个值呢

暴力法就太麻烦了,这里我自己想出一种贪心的方法,利用了stack,并修改了工具栈,从这里凸显出我对数据结构的灵活运用

举个例子吧, 数组为 11,45,34,23,17,23,45,27,34,给定值为 106(即为 45 + 34 +27)

数组排序后为 11,17,23,23,27,34,34,45,45

我设计的的算法是这样的,工具栈初始化及变化如下

1. 

11 < 106, 插入 17

2.

28 < 106, 插入23

3.

51 < 106, 插入 23

4.

74 < 106, 插入 27

5.

103 < 106 ,插入 34

6.

137 > 106, 出栈 34,然后把栈顶 27 扩大一下,换成其在数组里后面的值 34

7.

110 > 106 , 出栈 34,然后把栈顶 23 扩大一下,换成其在数组里后面的值 27

8.

78 < 106 ,  34 进栈

9.

112 > 106 ,  出栈 34,然后把栈顶 27 扩大一下,换成其在数组里后面的值 34

10.

85 < 106 ,34 进栈

11.

119 > 106, 出栈 34,然后把栈顶 34 扩大一下,换成其在数组里后面的值 34

12.

85 < 106 , 45 进栈

13.

130 > 106,出栈 45,然后把栈顶 34 扩大一下,换成其在数组里后面的值 45

14.

96 < 106 ,45 进栈

15.

141 > 106 ,出栈 45,然后把栈顶 45扩大一下,换成其在数组里后面的值 45

16.

96 < 106, 但此时 栈顶已经是数组里最后一个值,所以不再进栈而是  出栈 45,然后把栈顶 23扩大一下,换成其在数组里后面的值 23

相信大家已经看到我算法的规律了,说到这里实在不好意思,例子找的不好,弄得非常长,大家看懂得感觉很简单,看不懂感觉很恶心

直到最后我的栈 会变到一下情况,就是出口


例子不好之处,还请见谅,下面给出我的算法(C++代码表示)

// 求出数组里是否存在 n 个数的和等于某个值 SUM
	bool Array::Is_Sum_SomeData(int *data,unsigned int const length,unsigned int SUM)
	{
		// 异常输入
			if(data == NULL || length == 0)
			{
				cout<<"error input of SumK,data = "<

你可能感兴趣的:(算法,面试题)