所以,基本上我感觉非常愚蠢,因为this exercise,我花了4到5个小时尝试编码,到目前为止我还没有成功。
我已经意识到使用Longest Path方法通过树遍历可以更容易地解决这个问题,但我不确定(你能否向我确认一下。),可能会过度杀死,因为它应该是一个容易出问题的问题,所以,请你帮助我提供一些指导或基本步骤或算法方法来解决这个问题?各种帮助当然值得赞赏。
PS。我通常会发布一些关于我到目前为止所做的事情的代码,但我相信到目前为止,一切都是错误的,我宁愿从头开始,至少在想法方面。
感谢。
根据请求,这里是根据解决练习的接受答案输入的代码:
def get_max_sum(matrix)
(1...matrix.length).each do |index|
flag = 0
matrix[index].each_with_index do |e, i|
add = (matrix[index-1][flag] > matrix[index-1][flag+1]) ? matrix[index-1][flag] : matrix[index-1][flag+1]
e += add
matrix[index][i] = e
flag = flag + 1
end
end
matrix[-1][0]
end
矩阵参数是一个数组数组,每个数组代表三角形中的一行。
答案 0 :(得分:6)
如果从底部开始并逐步提升,这个问题很容易。考虑三角形
1
1 2
4 1 2
2 3 1 1
查看倒数第二行。如果通过三角形的某个路径到达4,你将向右移动到3,得到7的总和(加上它上面的路径中的任何东西)。如果你已经达到1,你将向左移动到3,得到4的总和(加上它上面的路径中的任何东西)。如果你在2,你可以移动任何一种方式获得3的总和(加上它上面的路径中的任何东西)。因此,通过用总和替换倒数第二行,三角形
1
1 2
7 4 3
将具有与原始三角形相同的最大和路径。现在以递减三角形递归地执行相同的过程。从倒数第二行的1开始向左移动到7,得到8的总和,从2向左移动到4,得到6的总和。现在看起来像减少的三角形
1
8 6
最后,从倒数第二行的1开始向左移动到8,总和为9,这就是问题的答案。
还有一种自上而下的工作方法。在每一步中,将三角形中的每个数字替换为通向该数字的任何路径的最大总和。从顶部开始,三角形开始
1
然后第二行被其总和替换
1
2 3
然后是第三行
1
2 3
6 4 5
最后是第四行
1
2 3
6 4 5
8 9 6 6
答案是底行中最大的总和,即9。我总是发现自上而下的方法比自下而上的方法更难管理,但这两种算法是相互对立的,所以它是你选择哪个实施。自上而下的方法确实具有以下优势:您可以在读取数据时累积下一行;使用自下而上的方法,您必须在计算任何总和之前读取并存储整个输入。
我会留给你写代码。执行此操作时,请记住,您一次只需要存储两行,即前一行和下一行。哪个是上一个,哪个是下一个取决于您是自上而下还是自下而上 - 前一行是您刚刚填写的行,下一行是您当前正在处理的行,这意味着如果你自上而下工作,下一行的总和比上一行多一个,如果你自下而上工作,下一行的总和比前一行少一个。请在工作时发布您的代码,以便其他人可以从您的努力中学习。
顺便说一下,这个问题最初来自Project Euler。 Code Chef偷了它们,显然没有归属,这真的不是一件好事。
答案 1 :(得分:1)
注意:原始帖子中的问题陈述假设一个严格的直角三角形:
on each path the next number is located on the row below,
more precisely either directly below or below and one place to the right.
另请查看他们提供的示例以确认这一点。
解答:
1]使用二维数组存储三角形
根据规则重新计算三角形
走三角形的最后一行 - 即基数 - 以找到最大值。
CODE:
import java.util.Arrays;
public class NumberTriangle {
//MAIN IS FOR TESTING ONLY
public static void main(String[] ars) {
int[][] input = { { 1 }, { 4, 8 }, { 9, 8, 7 }, { 1, 3, 6, 9 },
{ 7, 5, 2, 7, 3 } };
int max = compute(input);// answer: max length
// not necessary; but shows new triangle
for (int[] A : input)
System.out.println(Arrays.toString(A));
// print the answer
System.out.println("Largest number: " + max);
}
//THIS IS THE SOLUTION
public static int compute(int[][] input) {
//compute new triangle
for (int y = 1; y < input.length; y++)
for (int x = 0; x < input[y].length; x++) {
int first = x - 1 > 0 ? x - 1 : 0;
int last = x < input[y - 1].length ? x
: input[y - 1].length - 1;
int max = Math.max(input[y - 1][last], input[y - 1][first]);
input[y][x] += max;
}
//extract max value;
int max = -1;
int lastRow = input[input.length - 1].length;
for (int x = 0, y = input.length - 1; x < lastRow; x++)
if (max < input[y][x])
max = input[y][x];
return max;
}// compute
}
测试用例的答案:
[1]
[5, 9]
[14, 17, 16]
[15, 20, 23, 25]
[22, 25, 25, 32, 28]
Largest number: 32
答案 2 :(得分:0)
最长路径寻找方法对我来说感觉不对,因为每条路径都是N-1边长。我想我会假装输入是一个二叉树并找到树中最大的元素 - 找到底部两行的最大总和,在倒数第二行记忆结果,然后向上移动另一行行。 (我希望这有点意义......)