如何获得最小总和的数组

时间:2013-04-26 15:52:03

标签: algorithm

我接受了这个面试问题,我完全没了。你们怎么解决这个问题:

从数组的开头到最后,以最小化你所登陆的元素的总和。

  1. 您可以移动到下一个元素,即从索引1转到索引2.
  2. 或者你可以跳过一个元素。即从索引1到索引3。

3 个答案:

答案 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)解决方案!