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;
}
}
循环有两种基本形式:
-
对于每个,for-i或有时称为的范围用于
将其用于可计数的迭代次数。例如,具有要循环通过的数组或集合。
-
while
和do-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中的所有循环,包括概念、术语、示例、风险