用窗口查找总和

时间:2014-03-11 21:02:02

标签: java algorithm

我试图解决这个问题: 有一个列表和一个窗口。窗口显示列表中要添加的元素数量,例如:

[4, 2, 73, 11, -5]和窗口大小2应返回[6, 75, 84, 6]

所以我编写了如下代码:

public static void main(String args[]){
    LinkedList<Integer> l=new LinkedList<Integer>();
    l.add(5);
    l.add(8);
    l.add(9);
    l.add(3);
    l.add(4);
    l.add(1);
    int window=2;
    int[] sum=new int[l.size()-window+1];

    for(int i=0;i<=l.size()-window; i++){
        for(int j=0;j<window; j++){
            sum[i]=sum[i]+l.get(i+j);
        }
    }
}

由于时间复杂度很高,这不是一种有效的解决方案。任何帮助,将不胜感激。

3 个答案:

答案 0 :(得分:4)

通过识别当窗口从一个索引滑动到下一个索引时,您应该能够获得更好的性能,一个总和与下一个总和之间的唯一区别是恰好添加了一个项目并且减去了一个项目。

j for循环的每次迭代中,您无需在i for循环中重新计算总和。首先计算第一个window数字的初始总和,这将照顾i0。然后在i循环的每次迭代中,从1开始,将索引window + i处的值加上总和,并减去索引i处的值。这将改善性能,尤其是对于window的高值。

答案 1 :(得分:1)

解决此问题的一种更简单的方法是,不是在窗口中执行两个循环来获取部分和,而是可以将每个求和结果保存在名为current的变量中。然后每次将窗口向右移动时,一个元素被移出并移入一个新元素。因此,您可以通过添加新的移入元素并减去旧的移出元素来更新窗口总和。这样可以节省一些计算量。总时间复杂度为O(N)。代码如下所列。

   public class WindowSum {
        public static int[] windowSum(int[] arr, int windowSize) {
            int[] sum = new int[arr.length-windowSize+1];
            int current = 0;
            for(int i=0; i<windowSize; i++)
                current += arr[i];
            sum[0] = current;
            for(int i=1; i<arr.length-windowSize+1; i++) {
                sum[i] = current + arr[i+windowSize-1] - arr[i-1];
                current = sum[i];
            }
            return sum;
        }

        public static void main(String[] args) {
            int[] num = {4, 2, 73, 11, -5};
            int[] sum = windowSum(num, 2);
            System.out.println(Arrays.toString(sum));
        }

    }

答案 2 :(得分:0)

这看起来像是一个家庭作业问题,所以我只是提示算法,而不是实际的代码:

  • 首先,计算第一个窗口的答案。将其保存在0插槽中。
  • 对于每个下一步,将窗口向右移动一次:添加落入窗口的新整数,然后减去旧的整数。将其保存在下一个插槽中。
  • 重复操作,直到窗口末尾到达输入数据的末尾。