【发布时间】:2017-05-10 18:33:03
【问题描述】:
给定一个长度为 n 的 int 数组,将数组分成 3 部分,并确保 2 个较小的部分尽可能大。
拆分规则:
- 选择给定数组的两个索引
a和b(0 - 第一部分的大小是:从索引 0 到 a-1(含)所有数组条目的总和
- 第二部分的大小是:从索引 a 到 b(含)所有数组条目的总和
- 第三部分的大小为:从 b+1 到 n-1(含)所有数组项的总和
- 可能有空的部分..
预期的输出是两个较小部分的总和(它们的大小)。
例如,n = 6 的数组和一些值被给出。
该解决方案计算a = 2,b = 3,将数组分成三部分:左边部分的大小为6 + 7 = 13,中间部分为8 + 9 = 17,右边部分为4 + 5 = 9。输出为13 + 9 = 22(两个较小部分的总和)。
图形表示:
更多示例:
[6, 8, 3, 5, 7, 2, 4, 6] 应该拆分成:
- 左 (
6 + 8 = 14) - 中间 (
3 + 5 + 7 = 15) - 对 (
2 + 4 + 6 = 12)
输出为14 + 12 = 26(两个较小部分的总和)
[9, 12, 4, 7, 10, 2, 5, 8, 11, 3] 应拆分为:
- 左 (
9 + 12 + 4 = 25) - 中间 (
7 + 10 + 2 + 5 = 24) - 对 (
8 + 11 + 3 = 22)
输出为22 + 24 = 46(两个较小部分的总和)
我的方法不适用于给定的测试用例:
// L is size of left part, M is size of middle part, R is size of right part
/* I start with all array entries in the middle part, then I put elements
out of the middle part into the left and right part (depending on which
is smaller) until one of them is larger than M, this approach works for
many cases, two exceptions are the first 2 arrays given as examples in
this post.
*/
long a = 1;
long b = n;
long L = R = 0;
long M = arr.sumOfAllArrayEntries;
long temp;
long[] arr = {9, 12, 4, 7, 10, 2, 5, 8, 11, 3};
while (M > Math.max(L, R)) {
if (L < R) {
// move leftmost element of M to L
temp = arr[(int) a++];
M -= temp;
L += temp;
}
else {
// move rightmost element of M to R
temp = arr[(int) b--];
M -= temp;
R += temp;
}
}
// finds maximum of M, L, R
temp = Math.max(M, Math.max(L, R));
// finds 2 smallest numbers out of M, L, R
if (temp == M)
temp = L + R;
else if (temp == L)
temp = M + R;
else if (temp == R)
temp = M + L;
// temp is equal to the sum of the 2 smaller parts
System.out.println("Output: " + temp);
【问题讨论】: