一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值

前几天去面试的时候,有家公司好奇怪进行机试,然后我就见到这道题,然后我当时好像做了一天了才做出来。中途的时候好像到2点多的时候以为做出来了。然后给了一组数据给我,然后发现有两组数据是异常的,然后就打断点在那里跟后来改了一些东西之后发先运行时报错和那个死循环,后来想到另外一种相似的思路,把之前的代码都注析掉了然后再来写,到7点钟的时候写完,但是调试还是出现运行时错误和死循环,到8点左右把程序调通,我想拍照回去研究研究的时候被拒绝了说公司规矩,然后我觉得那么短的题目很容易就能记住,回来进行构思另外一种写法然后写出来了,结果速度很慢一个21长度的数组要几秒钟才能算出结果,30个长度已经看不到停止的时候了。后来昨天有时间研究了下,改进了代码最终做一个随机数组好像能在几百毫秒算出分组情况吧,然后我又怕忘记之前写的代码所以就把这些代码记下来吧。

#include<vector>
#include<list>
#include<iostream>

using namespace std;

typedef vector<int> intArray_t;

int sumOfArray(const vector<int> &array) {
	int sum = 0;
	int size = array.size();
	for (int i = 0; i < size; i++) {
		sum += array.at(i);
	}
	return sum;
}

bool maxDivFun(list<int> &array, vector<intArray_t> &result, int groupSize, int preSize, vector<int> &preArray, list<int>::iterator iter) {
	while (iter != array.end()) {
		if ((preSize + *iter) <= groupSize) {
			preArray.push_back(*iter);
			bool isFirst = false;
			if (iter == array.begin()) {
				isFirst = true;
			}
			array.erase(iter++);
			if ((preSize + preArray.back()) == groupSize) {
				if (array.empty()) {
					result.push_back(preArray);
					return true;
				}
				else {

					list<int> retList(array.begin(), array.end());
					vector<int> grpArray(1, retList.back());
					retList.pop_back();
					if (maxDivFun(retList, result, groupSize, grpArray.at(0), grpArray, retList.begin())) {
						result.push_back(preArray);
						return true;
					}

					if (!isFirst)
						iter--;
				}
			}
			else if (isFirst) {
				if (maxDivFun(array, result, groupSize, preSize + preArray.back(), preArray, iter))
					return true;
			}
			else if (maxDivFun(array, result, groupSize, preSize + preArray.back(), preArray, iter--))
				return true;
			if (isFirst) {
				iter = array.begin();
				array.insert(iter, preArray.back());
			}
			else
				array.insert(++iter, preArray.back());
			preArray.pop_back();
		}
		else
			break;
	}
	return false;
}

void maxDiv(const vector<int> &array, vector<intArray_t> &result) {
	if (array.empty())
		return;
	list<int> retList(array.begin(), array.end());
	retList.sort();
	int maxNum = retList.back();
	vector<int> preArray(1, maxNum);
	if (retList.size() == 1) {
		result.push_back(preArray);
		return;
	}
	retList.pop_back();
	int sum = sumOfArray(array);
	if (sum % maxNum == 0) {
		result.push_back(preArray);
		int n = 0;
		while (retList.back() == maxNum) {
			result.push_back(preArray);
			retList.pop_back();
			if (retList.empty())
				return;
			n++;
		}
		preArray.at(0) = retList.back();
		retList.pop_back();
		if (maxDivFun(retList, result, maxNum, preArray.at(0), preArray, retList.begin())) {
			return;
		}
		retList.push_back(preArray.at(0));
		for (; n != 0; n--) {
			retList.push_back(maxNum);
		}
		preArray.at(0) = maxNum;
		result.clear();
	}
	for (int i = maxNum + 1; i <= sum; i++) {
		if (sum % i == 0 && maxDivFun(retList, result, i, preArray.at(0), preArray, retList.begin())) {
			break;
		}
	}
}

然后我的测试代码很简单跑完下面这段程序我的电脑要两秒多的时间吧。

int main() {
	int a[10000];
	//int a[] = { 1, 2, 4, 5, 100 };
	//int a[] = { 1, 1, 1, 1, 1, 1 };
	//int a[] = { 3, 3, 4, 6, 2 };
	for (int i = 0; i < (sizeof(a) / sizeof(int)); i++) {
		a[i] = i + 1;
	//	while ((a[i] = (rand() % 1000)) == 0);
	}
	vector<int> array(a, a + (sizeof(a)/sizeof(int)));
	vector<intArray_t> result;
	maxDiv(array, result);
	cout << "{";
	int resultSize = result.size();
	for (int i = 0; i < resultSize; i++) {
		if (i != 0)
			cout << ", ";
		cout << "{";
		vector<int> group = result.at(i);
		int groupSize = group.size();
		for (int j = 0; j < groupSize; j++) {
			if (j != 0)
				cout << ", ";
			cout << group.at(j);
		}
		cout << "}";
	}
	cout << "}";
	cout << "\n";
	cout << "The max group num that can divide to have same sum group is: " << resultSize;
	return 0;
}

但是我又想了很久,一种改进的方法的雏形已经出现在我的脑海中,有时间再改,到时候调试没问题的话也放上来。

时间: 2024-10-12 00:34:56

一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值的相关文章

软件工程课程作业(四)--返回一个整数数组中最大子数组的和

伙伴链接:http://www.cnblogs.com/haoying1994/ 一.设计思想 本实验要求输入一个正负数混合的整型数组,长度不限,在此数组的所有子数组中找到和最大的数组,并求出相应数组的和,且时间复杂度为O(n).我们在课堂上共同讨论了多种解决方案,这些将在下面可能的解决方案中展示,在听了同学的思路和老师的讲解之后, 我们最终选取了老师课堂上描述的比较简便的思路.如下: 在输入数组的环节,采用for无限循环加if判断截止,直到触发回车键为止,将数组记录到Array中,数组长度记录

课后实验4--返回一个整数数组中最大子数组的和

伙伴链接:http://www.cnblogs.com/chengqiqin07/ 一.设计思想 本实验要求输入一个正负数混合的整型数组,长度不限,在此数组的所有子数组中找到和最大的数组,并求出相应数组的和,且时间复杂度为O(n).我们在课堂上共同讨论了多种解决方案,这些将在下面可能的解决方案中展示,在听了同学的思路和老师的讲解之后, 我们最终选取了老师课堂上描述的比较简便的思路.如下: 在输入数组的环节,采用for无限循环加if判断截止,直到触发回车键为止,将数组记录到Array中,数组长度记

返回一个整数数组(环形数组)中最大子数组的和

一.实验题目 题目:返回一个整数数组中最大子数组的和. 要求:      输入一个整形数组,数组里有整数也有负数.      数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.      如果数组A[0]……A[j-1]首尾相邻,允许A[i-1],……A[n-1],A[0]……A[j-1]之和最大.      同时返回最大子数组的位置. 求所有子数组的和的最大值.要求时间复杂度为O(n). 二.实验思路 由于这次所要求的子数组相当于一个环形的数组,所以就想到了类似数字右循环的形式来

找出一个整数数组的和最大的连续子数组

题目: 给任意一个整数数组,找出这个数组的和最大的连续子数组(子数组的和最大且子数组连续).要求:算法的时间复杂度为O(n). 程序设计思想: 1:用maxValue记录当前连续子数组和为最大的和的值,初始化其值为:maxValue=a[0].注:记数组为a[n]. 2:这个过程总的思想就是,从数组头开始往后,每次加进一个值,它们的和记为tempValue,若tempValue比新加进来的数值本身要小,应该从这个位置开始重新开始计算tempValue的值.而每次的tempValue都应该和max

一个整数数组中最大字数组二

返回整数数组中最大子数组的和2 1.题目: 返回一个整数数组中最大子数组的和. 2.要求: 1)要求程序必须能处理1000个元素: 2)每个元素都是int32类型的. 3.设计思路: 处理1000个元素时让用户自己输入想要的数组长度,看看运行时出处理时间的长短,再在源程序中改善这一问题. 处理大数溢出时,由于随机函数生成的数不算太大,我们尽量让其最终存入数组的元素接近最大范围,进而求和时才可能出现大数溢出的情况. 4.源代码: 1 #include<iostream> 2 #include&l

软件工程结对开发——返回一个整数数组中最大子数组的和(JAVA)

题目:返回一个整数数组中最大子数组的和. 要求: 输入一个整型数组,数组里有正数也有负数: 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和: 求所有子数组的和的最大值.要求时间复杂度为O(n): 一.设计思想 1.首先随机产生一个数组,数组长度可自行输入,该数组里有正数也有负数. 2.从数组中第一个元素a[0]开始,依次计算a[0].a[0]+a[1].a[0]+a[1]+...+a[i]的值,即从a[0]开始的每个子数组的和,取出最大值. 3.再从数组第二个元素a[1]开始,依

返回一个整数数组中最大子数组的和(加强版)

题目:返回一个整数数组中最大子数组的和 要求:让数组手尾相连,构成一个环,同时返回最大子数组的位置 设计思想: 1.将环断开,成为一条线,分析这条线上的最大子数组,找到最大子数组,便可以找到最大子数组的起点和终点. 2.然后将终点看作起点,将起点看作终点,将线连成环,在进行寻找最大子数组(寻找时不算上起点和终点). 3.最后将先后找到的两个最大子数组连在一起就形成了这个整数组环的最大子数组,然后将记录的起点和终点输出出来,返回最大子数组的位置. 源代码: #include<iostream>

把一个整数数组中所有的非0整数移到左边

1.一个整数数组,把非0的整数移到左边,对整数的顺序不做要求.写一个函数实现,并返回数组的非0整数个数.不使用额外的存储.比如: 初始数组为:[ 1, 0, 2, 0, 0, 3, 4 ],处理后的数组是:[ 4, 1, 3, 2, 0, 0, 0 ],函数返回非0整数的个数4. 解答:两个指针,一个从左向右移动,一个从右向左移动. int moveLeft(int* arr, int len) { if (arr == NULL || len <= 0) return -1; int i =

返回一个整数数组中最大数组的和

一:题目内容及设计思路 1.题目: 返回一个整数数组中最大数组的和 2.要求: (1)输入一个整数数组,数组里有正数也有负数. (2)数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. (3)求所有子数组的和的最大值.有球时间复杂度为O(n). 3.设计思路: (1)利用while循环输入各个整数,用getchar()函数判断while循环是否结束,当用户按下回车键时,即getchar()=='\n'时,跳出while循环: (2)记录下循环的次数,即数组长度: (3)调用函数Co

返回一个整数数组中最大子数组的和。(二人结对编程)

 题目:返回一个整数数组中最大子数组的和. 要求: 1.要求程序必须能处理1000 个元素: 2.每个元素是int32 类型的,出现子数组之和大于整型表示的最大范围会出现什么情况: 3.输入一个整型数组,数组里有正数也有负数. 4.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 5.求所有子数组的和的最大值.要求时间复杂度为O(n).  设计思想:(1)将数组大小定义为n,用户输入p的值以确定该数组的长度,对于这n个元素用随机函数进行生成,每个元素定义为int32类型.(2)为