簡體   English   中英

減少時間復雜度/優化解決方案

[英]Reducing the time complexity/Optimizing the solution

座右銘是找到N以下3或5的所有倍數的和。

這是我的代碼:

public class Solution
 {
 public static void main(String[] args)
  {
    Scanner in = new Scanner(System.in);
    int t = in.nextInt();
    long n=0;
    long sum=0;

    for(int a0 = 0; a0 < t; a0++)
    {
        n = in.nextInt();
        sum=0;
         for(long i=1;i<n;i++)
        {
        if(i%3==0 || i%5==0)

            sum = sum + i;
        }
   System.out.println(sum); 
    }
 }
}

對於某些測試用例,要花費超過1秒的時間。 誰能幫助我,以減少時間的復雜性?

我們可以找到小於N的所有d的所有倍數的和,作為算術級數的總和(它們的總和等於d + 2*d + 3*d + ... )。

long multiplesSum(long N, long d) {
    long highestMultiple = (N-1) / d * d;
    long numberOfMultiples = highestMultiple / d;
    return (d + highestMultiple) * numberOfMultiples / 2;
}

那么結果將等於:

long resultSum(long N) {
    return multiplesSum(N, 3) + multiplesSum(N, 5) - multiplesSum(N, 3*5);
}

我們需要減去multiplesSum(N, 15)因為有些數字是35倍數,所以我們將它們加了兩次。

復雜度: O(1)

在這種情況下,您無法降低時間復雜度,因為每組數字仍然有O(N) 但是,您可以使用整數除法來減少常數乘數

static int findMultiples(int N, int s)
{
    int c = N / s, sum = 0;
    for (int i = 0, k = s; i < c; i++, k += s)
        sum += k;
    return sum;
}

這樣,您只循環遍歷多個倍數而不是整個范圍[0,N]。

請注意,您將需要執行findMultiples(N, 3) + findMultiples(N, 5) - findMultiples(N, 15) ,以刪除3和5的重復倍數。因此,循環數為N / 3 + N / 5 + N / 15 = 0.6N,而不是N。

編輯:通常,任意數量的除數的解決方案是sum(findMultiples(N,divisor_i) - findMultiples(N,LCM(all_divisors)) ;但是,只有sum(1/divisor_i) + 1/LCM(all_divisors) < 1才值得這樣做sum(1/divisor_i) + 1/LCM(all_divisors) < 1 ,否則將會有更多的循環,幸運的是,這對於2個除數永遠不會成立。

從1到(包括)N的所有數字的總和已知為N(N + 1)/ 2(無需迭代)。

因此,從K到KM的K的所有倍數之和是上述公式的K倍,得出KM(M + 1)/ 2。

將此與@meowgoesthedog的findMultiples(N,3)+ findMultiples(N,5)-findMultiples(N,15)的想法結合起來,您將獲得一個固定時間的解決方案。

解決問題的方法。解決問題的最快方法。

import java.util.*;
class Solution {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int t = in.nextInt();
        while(t!=0)
        {
            long a=in.nextLong();
            long q=a-1;
            long aa=q/3;
            long bb=q/5;
            long cc=q/15;
            long aaa=((aa*(aa+1))/2)*3;
            long bbb=((bb*(bb+1))/2)*5;
            long ccc=((cc*(cc+1))/2)*15;
            System.out.println(aaa+bbb-ccc);
         t-=1;}
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM