如何优化我的代码?

时间:2017-02-23 11:56:38

标签: java data-structures

第一行将包含由单个空格分隔的两个整数N和M. 下一行将包含由单个空格分隔的三个整数a,b和k。 N是序列的长度。 M不是对该序列执行的操作。 a是序列的起始索引,b是序列的结束索引,我必须将k添加到a和k之间的所有元素。(我必须在N长度序列上执行M次)

这是我的代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Solution {
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner sc = new Scanner(System.in);
        int n=sc.nextInt();
        int m=sc.nextInt();
        List l= new ArrayList(Collections.nCopies(n, 0));
        //System.out.println(l);

        for(int i=1;i<=m;i++){
            int a=sc.nextInt();
            int b=sc.nextInt();
            int k=sc.nextInt();
            for(int j=0;j<n;j++){
                //if((a-j)<=b){
                if(j+1>=a && j+1<=b){
                    int ab= (int) l.get(j);
                    int sum=ab+k;
                    l.set(j,sum);
                }
            }
        }
        int total=0;
        total=(int) l.get(0);
        for(int i=0;i<n;i++){
            int num=(int) l.get(i);
            if(num>total){
                total=num;
            }
        }
        System.out.println(total);
    }
}

Qyestion: 我的代码由于超时而失败,还有其他一些我不知道的问题..请帮助解决这个问题或优化我的代码。

1 个答案:

答案 0 :(得分:2)

您只需在该范围的start处添加该数字,然后在end之后减去该数字,而不是在某个范围内实际添加相同的数字。在所有操作之后,此数组的累积总和实际上与将k添加到给定范围中的所有元素相同。您可以使用此逻辑来解决此问题:

  • 创建一个大小为n + 2或更大的数组:

    long arr[] = new long[n+2];
    
  • 所有m操作的
  • (在阅读abk的值后),将k添加到{{1}从arr[a]中减去k

    arr[b+1]
  • 现在计算上面数组的累积和,同时计算最大元素:

    arr[a]+=k;
    arr[b+1]-=k;
    
  • 现在打印最终答案long mx = 0; for(int i=1;i<=n;i++) { arr[i]+=arr[i-1]; mx=Math.max(mx,arr[i]); }

时间复杂度 = mx O(1)运算的时间复杂度(分别为ma的加法和减法)+累计和的时间复杂度 = O(m + n)

希望这有帮助。