一堆整数,分成三组,使每组和尽量相等。一道前端面试题引发的思考。

学生在阿里面试时笔试中的一道题目,这道题说简单不简单,说难也不难。

题目主要考察的是算法,大抵不涉及数据结构。

考察什么算法呢?主要是考察编程基本功和一定的想像力。

先粗略想了一下,竟没想出什么好手段。按惯例,先百度了一下,好家伙,这道题目看来早就有了,虽表现形式不尽相同,但大抵旨意基本一致。

网络上各路大神,也是八仙过海,各显其能,乱哄哄你方唱罢我登场。

抱着对同行的敬意,沐浴、更衣、净手、上香。。。

然后,翻来翻去,大多都是一而十,十而百,百而千千万的转载,没什么创新,也没什么实质性内容。

少数给出解决方案,或者代码的,都存在着不小的漏洞,要么给出的答案准确率不行,要么效率不行,代码啰嗦冗长,仿佛ngkm ihvy r yjef。

抱着对职业的敬意,认真思考了一下,以下给出js的大致实现(因为题目就是要求js实现),其它语言依据程序逻辑,稍加变通即可。

代码千万行,注释第一行。走起。

/*******************************************************************************
 *
 *4.有一堆整数,请把它们分成三份,确保每一份和尽量相等。
 * [11,42,23,4,5,6,4,5,6,11,23,42,56,78,90]
 *
 ******************************************************************************/
//把数组分成n份,每一份的和尽量相等,返回一个二维数组
function fun(total, n) {
	//先对整个数组进行排序
	total.sort((a, b) => a - b);

	//求和
	var sum = 0;
	for (var i = 0; i < total.length; i++) {
		sum += total[i];
	}

	var avg = Math.ceil(sum / n);

	//结果数组
	var result = []; //长度为n

	for (var i = 0; i < n; i++) {
		result[i] = [total.pop()];
		result[i].sum = result[i][0];

		//组成一个分数组
		while (result[i].sum < avg && total.length > 0) {
			for (var j = 0; j < total.length; j++) {
				if (result[i].sum + total[j] >= avg) {
					result[i].push(total[j]);
					result[i].sum += total[j];
					break;
				}
			}

			if (j == total.length) {
				result[i].push(total.pop());
				result[i].sum += result[i][result[i].length - 1];
			} else {
				//从数组中移除此元素
				total.splice(j, 1);
			}
		}

		sum -= result[i].sum;
		avg = Math.ceil(sum / (n - 1 - i));

	}
	return result;
}

写完之后,我又陷入了深深的思考。

 

完。

posted @ 2021-03-06 18:20  一千堆雪  阅读(585)  评论(1编辑  收藏  举报