【问题标题】:increasing code performance of codility提高 codility 的代码性能
【发布时间】:2015-01-27 19:29:24
【问题描述】:

今天我听说了一个名为 codility 的网站,用户可以在该网站上进行各种编程测试以检查其代码的性能。

当我开始时,他们向我展示了这个示例测试,

任务描述一只小青蛙想要到达另一边 路。青蛙当前位于位置 X 并想到达 大于或等于 Y 的位置。小青蛙总是跳 固定距离,D。计算最小的跳跃次数 青蛙必须执行才能达到目标。

写一个函数: class Solution { public int solution(int X, int Y, int D); } 即,给定三个整数XYD,返回从位置X 到等于或大于Y 的位置的最小跳转次数。

例如, 给定:
X = 10
Y = 85
D = 30 函数应该返回3, 因为青蛙的位置如下:

第一次跳跃后, 在位置 10 + 30 = 40

第二次跳跃后,位置 10 + 30 + 30 = 70

第三次跳跃后,位置 10 + 30 + 30 + 30 = 100

假设:X、Y、D为范围内的整数

[1..1,000,000,000]; X ≤ Y。复杂度:预期最坏情况时间

复杂度为 O(1);预期的最坏情况空间复杂度为 O(1)。

这个问题很简单,我花了大约 2 分钟来写解决方案,下面是,

class Solution {
    public int solution(int X, int Y, int D) {

        int p = 0;
        while (X < Y){
            p++;
            X = X + D;
        }
    return p;
    }
}

但是,测试结果显示我的代码的性能只是20%,而我的得分只是55%

这是结果的链接,https://codility.com/demo/results/demo66WP2H-K25/

这么简单的代码,我只用了一个while循环,怎么可能做得更快?

【问题讨论】:

  • 使用除法?你必须走2389米。你走的每一步都是1米。你需要多少步?
  • 基于@JB 的评论,系统会询问您 D 进入 Y-X 的次数(如果有余数,则四舍五入)。
  • 在 C 中:返回 (y-x)/d + ((y-x)%d!=0);
  • 他们已经很清楚地说预期的复杂性是 O(1),而您的解决方案的复杂性是 O(Y-X)。也就是说,O(n)。这个问题不需要循环。

标签: java


【解决方案1】:

基础数学:

X + nD >= Y
nD >= Y - X
n >= (Y - X) / D

n 的最小值将是 (Y - X) 除以 D 的结果。

此操作的大 O 分析:

  • 复杂性:O(1)。这是一种差异、一种划分和一种总结
  • 最坏情况下的空间复杂度为 O(1):您最多可以再拥有 3 个变量:
    • Y - X 的差异,让我们将其分配给 Z。
    • Z 除以 D,我们将其分配给 E。
    • 将 E 向上取整,让我们将其分配给 R(从结果)。

【讨论】:

  • 另外需要注意的是这个函数运行在O(1)中
  • 你能解释一下为什么向上舍入而不是向下舍入吗?
  • @KickButtowski 来自示例:X = 10, Y = 85, D = 30,我们需要得到从 X 点到 Y 点或以上的距离 D 必须经过多少步。然后,使用答案中的公式和变量:Z = 75,E = 75 / 30 = 2.5,R = 3(向上取整 2.5)。
  • @dbarnes 答案已更新以反映大 O 分析的结果。
  • @bhuvesh 使用int result = (int)(Math.ceil(1.0*(Y - X) / D));
【解决方案2】:

Java(单行),正确性 100%,性能 100%,任务分数 100%

// you can also use imports, for example:
// import java.util.*;

// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");

class Solution {
    public int solution(int X, int Y, int D) {
      return (int) Math.ceil((double) (Y - X) / (double) D);
    }
}

【讨论】:

  • 我的,第一次尝试 11%,然后我尝试你的 100%,请解释一下数学。
【解决方案3】:

这是 100% 总分 Python 解决方案

def solution(X, Y, D):
    # write your code in Python 3.6
    s = (Y-X)/D
    return int(-(-s // 1))

【讨论】:

    【解决方案4】:
    class Solution {
      public int solution(int x, int y, int d) {
        return (y - x + d - 1) / d;
      }
    }
    

    【讨论】:

      【解决方案5】:
      class Solution {
          public int solution(int x, int y, int d) {
              // write your code in Java SE 8
              System.out.println("this is a debug message"+(y-x)%d);
              if((y-x)%d == 0)
                  return ((y-x)/d);
              else
                  return (((y-x)/d)+1);
          }
      }
      

      【讨论】:

      • 如果您需要解决方案的解释,请告诉我
      【解决方案6】:

      C# 满分 100 分,得 100 分

      using System;
      // you can also use other imports, for example:
      // using System.Collections.Generic;
      
      // you can write to stdout for debugging purposes, e.g.
      // Console.WriteLine("this is a debug message");
      
      class Solution {
          public int solution(int X, int Y, int D) {
      
              int Len= Y-X;
              if (Len%D==0)
              {
                  return Len/D;
              }
              else
              {
                  return (Len/D)+1;
              }
          }
      }
      

      【讨论】:

        【解决方案7】:

        这是 Scala 解决方案:

        def solution(X: Int, Y: Int, D: Int): Int = {
        
            //divide distance (Y-X) with fixed jump distance. If there is reminder then add 1 to result to
            // cover that part with one jump
        
            val jumps  =   (Y-X) / D  + (if(((Y-X) % D) >0 ) 1 else 0)
        
            jumps
        
          }
        

        性能:https://codility.com/demo/results/trainingTQS547-ZQW/

        【讨论】:

          【解决方案8】:

          Javascript 解决方案,100/100,比现有答案短:

          function solution(Y, Y, D) {
           return Math.ceil((Y - X) / D);
          }
          

          【讨论】:

            【解决方案9】:

            这是一个将测试性能提高到 100% 的解决方案

            class Solution {
                public int solution(int X, int Y, int D) {
                    if (X >= Y) return 0;
            
                    if (D == 0) return -1;
            
                    int minJump = 0;
            
                    if ((Y - X) % D == 0) {
                        minJump = (Y - X) / D;
                    } else minJump= (Y - X) / D +1;
            
                    return minJump;
                }
            }
            

            【讨论】:

              【解决方案10】:

              JavaScript 解决方案 100/100

              function solution (x,y,d) {
                  if ((y-x) % d === 0) {
                      return (y-x)/d;
                  } else {
                      return Math.ceil((y-x)/d);
                  }
              }
              

              【讨论】:

              • 如果你要使用 Math.ceil(..),去掉 if:function solution (x,y,d) { return Math.ceil((y-x)/d); }
              【解决方案11】:

              使用Java完美代码

              100 score code in Java
              

              公共 int 解决方案(int X,int Y,int D){

              如果(X

                if(X==Y)
                        return 0;
              
                   if((Y-X)%D==0)
                       return (Y-X)/D;
                   else
                       return (((Y-X)/D)+1);  
              
              }
              

              【讨论】:

                【解决方案12】:

                这是使用 java 的更正代码,通过率达到 91%

                int solution(int A[]) {
                
                        int len = A.length;
                        if (len == 2) {
                            return Math.abs(A[1] - A[0]);
                        }
                        int[] sumArray = new int[A.length];
                        int sum = 0;
                        for (int j = 0; j < A.length; j++) {
                            sum = sum + A[j];
                            sumArray[j] = sum;
                        }
                        int min = Integer.MAX_VALUE;
                        for (int j = 0; j < sumArray.length; j++) {
                            int difference = Math.abs(sum - 2 * sumArray[j]);
                            // System.out.println(difference);
                            if (difference < min)
                                min = difference;
                        }
                        return min;
                    }
                

                【讨论】:

                  【解决方案13】:

                  这是我的 100% (C#) 解决方案:

                         int result = 0;
                          if (y <= x || d == 0)
                          {
                              result = 0;
                          }
                          else
                          {
                              result = (y - x + d - 1) / d;
                  
                          }
                  
                          return result;
                  

                  【讨论】:

                  • 请描述您的解决方案并解释它如何解决问题中的问题。
                  【解决方案14】:

                  这是我的 PHP 解决方案,100% 性能。

                     function solution($X, $Y, $D) {
                         return (int)ceil(($Y-$X)/$D); //ceils returns a float and so we cast (int)
                     }
                  

                  【讨论】:

                    【解决方案15】:

                    Y-X 为您提供对象必须行进的实际距离,如果该距离可直接由对象跳转(D)除,那么如果存在一些十进制值,则 ans 将是(sum/D),那么我们必须再添加 1即(sum/D)+1

                        int  sum=Y-X;
                        if(X!=Y && X<Y){
                        if(sum%D==0){
                            return (int )(sum/D);
                        }
                        else{
                            return ((int)(sum/D)+1);
                        }}
                        else{
                            return 0;
                        }
                    

                    【讨论】:

                      【解决方案16】:

                      我喜欢所有其他的解决方案,尤其是“(y - x + d - 1) / d”。这太棒了。这就是我想出的。

                      public int solution(int X, int Y, int D) {
                              if (X == Y || X > Y || D == 0) {
                                  return 0;
                              }
                      
                              int total = (Y - X) / D;
                              int left = (Y - X) - (D * total);
                      
                              if (left > 0) {
                                  total++;
                              }
                      
                              return total;
                          }
                      

                      【讨论】:

                        【解决方案17】:
                        // you can write to stdout for debugging purposes, e.g.
                        // console.log('this is a debug message');
                        
                        function solution(X, Y, D) {
                          let jumps = 0
                        
                          //If 0 -> 100 with 2 step
                          // Answer would be 100/2 = 50
                          //If 10 -> 100 with 2 step
                          //Answer would be (100 - 10) / 2 = 45
                          jumps = Math.ceil((Y - X) / D)
                          return jumps
                        }
                        

                        【讨论】:

                          【解决方案18】:

                          快速解决方案 100% PASS - O(1) 复杂度

                          import Foundation
                          import Glibc
                          
                          public func solution(_ X : Int, _ Y : Int, _ D : Int) -> Int {
                          
                          if X == Y {
                              return 0
                          }
                          
                          var jumps = (Y-X)/D
                          
                          if jumps * D + X < Y {
                              jumps += 1
                          }
                          
                          return jumps
                          
                          }
                          

                          【讨论】:

                            【解决方案19】:
                            import math
                            
                            
                            def solution(X, Y, D):
                                if (X >= Y): return 0
                            
                                if (D == 0): return -1
                            
                                minJump = 0
                            
                                #if ((Y - X) % D == 0):
                                minJump = math.ceil((Y - X) / D)
                                #else: 
                                    #minJump = math.ceil((Y - X) / D) +1
                            
                                return minJump
                            

                            【讨论】:

                            • 您好,欢迎来到 Stack Overflow!请拨打tour。感谢您提供答案,但您能否添加关于您的代码如何解决问题的说明?
                            【解决方案20】:

                            这个解决方案在 Java 11 中对我有用:

                            public int solution(int X, int Y, int D) {
                                return X == Y ? 0 : (Y - X - 1) / D + 1;
                            }
                            

                            正确性 100%,性能 100%,任务分数 100%

                            @Test
                            void solution() {
                                assertThat(task1.solution(0, 0, 30)).isEqualTo(0);
                                assertThat(task1.solution(10, 10, 10)).isEqualTo(0);
                                assertThat(task1.solution(10, 10, 30)).isEqualTo(0);
                                assertThat(task1.solution(10, 30, 30)).isEqualTo(1);
                                assertThat(task1.solution(10, 40, 30)).isEqualTo(1);
                                assertThat(task1.solution(10, 45, 30)).isEqualTo(2);
                                assertThat(task1.solution(10, 70, 30)).isEqualTo(2);
                                assertThat(task1.solution(10, 75, 30)).isEqualTo(3);
                                assertThat(task1.solution(10, 80, 30)).isEqualTo(3);
                                assertThat(task1.solution(10, 85, 30)).isEqualTo(3);
                                assertThat(task1.solution(10, 100, 30)).isEqualTo(3);
                                assertThat(task1.solution(10, 101, 30)).isEqualTo(4);
                                assertThat(task1.solution(10, 105, 30)).isEqualTo(4);
                                assertThat(task1.solution(10, 110, 30)).isEqualTo(4);
                            }
                            

                            【讨论】:

                              【解决方案21】:

                              这里是JS实现

                              function frogJumbs(x, y, d) {
                                  if ((y - x) % d == 0) {
                                      return Math.floor((y - x) / d);
                                  }
                                  return Math.floor((y - x) / d + 1);
                              }
                              console.log(frogJumbs(0, 150, 30));
                              

                              【讨论】:

                                【解决方案22】:

                                100% C# 解决方案:

                                public int solution(int X, int Y, int D)
                                {
                                  var result = Math.Ceiling((double)(Y - X) / D);
                                  return Convert.ToInt32(result);
                                }
                                

                                它将总距离除以跳跃长度并四舍五入结果。它是在多次尝试和一些网络搜索之后出现的。

                                【讨论】:

                                  猜你喜欢
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2010-10-07
                                  • 1970-01-01
                                  • 2020-08-16
                                  • 1970-01-01
                                  • 1970-01-01
                                  相关资源
                                  最近更新 更多