需要帮助理解算法的逻辑

时间:2013-10-25 06:18:07

标签: java algorithm

昨天在Codechef上有一个在线编码事件,我无法弄清楚如何解决one of the questions from it。简单地说:

给出一个 N 号码列表{ a 1 a 2 ,..., a N },找到范围[ L R ](1≤ L R N )最大化总和( a 1 + ... + 一个 <子> L-1 ) - ( <子> + ... + <子> - [R )+( <子> - [R 1 + ... + <子>名词)。

换句话说,您可以将列表的子部分乘以-1,并希望最大化结果列表的总和。

我查看了一些像this这样的解决方案,但无法弄清楚这家伙在做什么。

我该怎么做?

实施例

-2 3 -1 -4 -2

现在你可以将第3小节乘以3乘以得到

-2 3 1 4 2

这样sum(-2,3,1,4,2) = 8是这种情况下可能的最大值

3 个答案:

答案 0 :(得分:2)

如果我们能够找到数组中的最小序列而不是那个部分,如果我们乘以1会得到最大值。

例如,在此示例中:-2 3 -1 -4 -2最小序列为-1,-4,-2。如果我们将这个序列乘以1,它将最大化总和。所以问题是如何找到最小和序列。

这是O(N)解决方案:

如果数组包含所有+ ve而不是没有需要乘以-1的子数组。检查以下问题。 minimum sum subarray in O(N) by Kadane's algorithm

答案 1 :(得分:0)

您显示的算法基本上计算了任何元素的最大总和和当前总和。

注意:它使用与原始元素相反的符号构建数组

如果当前总和为负数,则它拒绝原始总和并开始与新元素的新总和。

如果当前总和是正数,那么这意味着包括前面的条目是有益的,它会将当前元素添加到总和中。

答案 2 :(得分:0)

如果我正确理解你的问题,听起来你想首先找到最小的子阵列,然后将其乘以-1并添加剩余的非否定值。

最小子阵列基本上与maximum subarray problem相反:

public class MaxSumTest {
    public static class MaxSumList{
        int s=0, e=0;
        List<Integer> maxList;

        public MaxSumList(List<Integer> l){
            //Calculate s and e indexes
            minSubarray(l);

            //Negate the minSubarray
            for(int i=s; i < e; i++)
                l.set(i, -l.get(i));

            //Store list
            maxList = l;
        }

        public int minSubarray(List<Integer> l){
            int tmpStart = s;
            int currMin = l.get(0);
            int globalMin = l.get(0);

            for(int i=1; i<l.size(); i++){
                if(currMin + l.get(i) > 0){
                    currMin = l.get(i);
                    tmpStart = i;
                }
                else{
                    currMin += l.get(i);
                }
                if(currMin < globalMin){
                    globalMin = currMin;
                    s = tmpStart;
                    e = i+1;
                }
            }
            return globalMin;
        }
    }
    public static void main(String... args){
        MaxSumList ms = new MaxSumList(Arrays.asList(new Integer[]{-2, 3, -1, -4, -2}));
        //Prints [-2, 3, 1, 4, 2]
        System.out.println(ms.maxList);
    }
}