显示超时错误的代码,可以有人解释,这个代码中的问题在哪里



LeetCode 485给定一个二进制数组nums,返回数组中连续1的最大数目。

示例1:

输入:nums=[1,1,0,1,1]输出:3说明:前两位或后三位是连续的1。连续1的最大数目为3。

---------解决方案:-------

public int findMaxConsecutiveOnes(int[] nums) {
    int maxConsSize = Integer.MIN_VALUE;
    
    int i = -1, j=-1, k=0;
    
    while(k<nums.length){
        while(k<nums.length && nums[k] == 1){
            k++;
            i++;
        }
        
        if(nums[k] == 0){
            maxConsSize = Math.max(maxConsSize,i-j);
            j = i;
        }
        
    }
    
    maxConsSize = Math.max(maxConsSize,i-j);
    
    return maxConsSize;
}

警告:这不是直接的答案(对于这个"做我的家庭作业"的问题(

您应该在IDE中使用(或学会使用(调试器(相信我,IDE,例如Eclipse会在您的入门阶段为您提供很大帮助(。

最简单(我并不是说最聪明(的方法,即如何知道程序在做什么(当你需要知道的时候,比如在本例中(是添加一些打印语句,例如将System.out.println("k=" + k)添加到你的程序中(在while循环中(。

你可能想看这个youtube视频。

您有一个无穷大循环。试着运行这个:

public class Test {
    public static void main(String[] args) {
        int maxConsSize = Integer.MIN_VALUE;
        int[] nums = {1,1,0,1,1,1};
        int i = -1, j=-1, k=0;
        System.out.println(nums.length);
        while(k<nums.length){
            while(k<nums.length && nums[k] == 1){
                k++;
                i++;
                System.out.println("k = " + k);
            }
            if(nums[k] == 0){
                maxConsSize = Math.max(maxConsSize,i-j);
                j = i;
            }
        }
        maxConsSize = Math.max(maxConsSize,i-j);
        System.out.println(maxConsSize);
    }
}

输出:

6
k = 1
k = 2

在读取第一个0之后,您处于无限循环中。你让这项任务变得非常复杂:(

这可能不是最好的解决方案,但它应该更快

public int findMaxConsecutiveOnes(int[] nums) {
    int maxCons = 0;
    int currentCons = 0;
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] == 0) {
           if (currentCons > maxCons) {
              maxCons = currentCons;
           }
              currentCons = 0;
           } else {
              currentCons++;
           }
        }
        if (currentCons > maxCons) {
            maxCons = currentCons;
        }
        
        return maxCons;
    }
}

循环有两种基本形式:

  1. 对于每个for-i或有时称为范围用于

    将其用于可计数的迭代次数。例如,具有要循环通过的数组或集合。

  2. whiledo-while(类似于其他编程语言中的直到循环(

    将其用于具有动态退出条件的对象。承受无限循环的风险!

您的问题:无限循环

您将while的第二种形式用于第一种形式的典型用例。在数组上迭代时,最好使用任何类型的for循环。

第二个总是承担无限循环的风险,没有适当的退出条件,或者当退出条件没有满足时(逻辑错误(。第一个在这方面是无风险的。

建议解决

建议从for-i开始:

// called for-i because the first iterator-variable is usually i
for(int i=0; i < nums.length, i++) {
  // do something with num[i]
  System.out.println(num[i]):
}

因为:

  • 它更安全,没有无限循环的风险
  • 迭代可以从第一行识别出来(可读性更好(
  • 循环体内无计数等

更简单和惯用的模式实际上是对每个:使用

for(int n : nums) {
  // do something with n
  System.out.println(n):
}

因为:

  • 它更安全,没有无限循环的风险
  • 迭代可以从第一行识别出来(可读性更好(
  • 不需要索引,适用于数组或列表
  • 根本不算

另请参阅:Java For Loop,For Each Loop,While,Do While Loop(ULTIMATE GUIDE(,一个深入的教程,涵盖了Java中的所有循环,包括概念、术语、示例、风险

相关内容

  • 没有找到相关文章

最新更新