我接受了这个面试问题,我完全没了。你们怎么解决这个问题:
从数组的开头到最后,以最小化你所登陆的元素的总和。
答案 0 :(得分:2)
假设您只从左向右移动,并且想要找到从0
元素的索引n - 1
到索引n
的方法,以便你所走的路径的总和是最小的。从索引i
开始,您只能前进到索引i + 1
或索引i + 2
。
观察到从索引0
到索引k
的最小路径是从索引0
到索引k - 1
的最小路径和最小路径之间的最小路径从索引0
到索引k- 2
的路径。根本没有其他途径可以采取。
因此,我们可以拥有动态编程解决方案:
DP[0] = A[0]
DP[1] = A[0] + A[1]
DP[k] = min(DP[0], DP[1]) + A[k]
A
是元素数组
DP
数组将存储索引i
中索引0
的元素的最小总和。
结果将在DP[n - 1]
。
答案 1 :(得分:1)
爪哇:
static int getMinSum(int elements[])
{
if (elements == null || elements.length == 0)
{
throw new IllegalArgumentException("No elements");
}
if (elements.length == 1)
{
return elements[0];
}
int minSum[] = new int[elements.length];
minSum[0] = elements[0];
minSum[1] = elements[0] + elements[1];
for (int i = 2; i < elements.length; i++)
{
minSum[i] = Math.min(minSum[i - 1] + elements[i], minSum[i - 2] + elements[i]);
}
return Math.min(minSum[elements.length - 2], minSum[elements.length - 1]);
}
输入:
int elements[] = { 1, -2, 3 };
System.out.println(getMinSum(elements));
输出:
-1
案例描述:
我们从指数0开始。我们必须采取1.现在我们可以去指数1或2.由于-2很有吸引力,我们选择它。现在我们可以转到索引2或跳转它。更好的跳跃和我们的总和最小1 +( - 2)= -1。
另一个例子(伪代码):
getMinSum({1, 1, 10, 1}) == 3
getMinSum({1, 1, 10, 100, 1000}) == 102
算法:
O(n)复杂性。动态编程。我们从左到右填充minSum数组。不变量:minSum[i] = min(minSum[i - 1] + elements[i] /* move by 1 */ , minSum[i - 2] + elements[i] /* hop */ )
。
答案 2 :(得分:0)
这似乎是动态编程解决方案的理想之地。
跟踪两个值,奇数/偶数
我们将Even
表示我们使用了之前的值,Odd
表示我们没有使用。
int Even = 0; int Odd = 0;
int length = arr.length;
从后面开始。我们可以接受这个号码。因此:
Even = arr[length];
Odd = 0;`
现在我们转到下一个有两个案例的元素。要么我们都是偶数,在这种情况下我们可以选择采用元素或跳过它。或者我们很奇怪,不得不采取这个元素。
int current = arr[length - 1]
Even = Min(Even + current, Odd + current);
Odd = Even;
我们可以制定一个循环并实现O(n)解决方案!