leetcode水题:Max Consecutive Ones

首次接触leetcode,于是选了几道水题来试试水,这一道算是想的蛮多的一道题,所以在这里详细记录一下。

先看题目要求:

Given a binary array, find the maximum number of consecutive 1s in this array.

Example 1:

Input: [1,1,0,1,1,1]
Output: 3
Explanation: The first two digits or the last three digits are consecutive 1s.
    The maximum number of consecutive 1s is 3.

Note:

  • The input array will only contain 0 and 1.
  • The length of input array is a positive integer and will not exceed 10,000

题目说得很简单,在一个序列中找出排在一起的数量最多的1的数量。

这个题本身很简单,只是中间出现了不同的思路,因而出现了不同的情况。接下来我将分别叙述3种思路及其具体情况。

第一种思路,是在序列中检索1,找到1之后一口气找出这个1之后有多少个1,之后和最大值判断进行取舍。函数包括2个循环,外循环和内循环。外循环用来找每个连续“1”序列的第一个“1”,内循环用来探索找到的这个连续“1”序列到底由多少个1构成。最初代码如下:

class Solution {
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
        int s = nums.size();
        int count = 0, max = 0;
        for (int i = 0; i < s; i++){                   //外循环,寻找“1”序列第一个“1”
            if (nums[i] == 1){
                count = 1;
                while(nums[i + 1] == 1){         //内循环,探索“1”序列长度
                    count++;
                    i++;
                }
                if (count > max)
                max = count;
                count = 0;
            }
        }
        return max;
    }
};

这个算法有一定的缺陷:

1,在内循环处未设置i的范围规定,因而在i = nums.size() - 1处会存在调用nums[nums.size()]的尴尬问题,不够严谨;

2,while(nums[i + 1] == 1)一句存在反复判断的问题,即当nums[i + 1]不为1时,在下一次外循环会再次判断,增加了时间消耗。

改善后代码如下:

class Solution {
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
        int s = nums.size();
        int count = 0, max = 0;
        for (int i = 0; i < s; i++){
            if (nums[i] == 1){
                count = 1;
                while(nums[i + 1] == 1 && i < s - 1){           // 增加 i < nums.size()的限定条件,弥补上述1缺陷
                    count++;
                    i++;
                }
                i++;                                                              // i在内循环结束后加1,弥补上述2缺陷
                if (count > max)
                max = count;
                count = 0;
            }
        }
        return max;
    }
};

思路一,完结。

第二种思路,与第一种思路相比,只有1层循环,我称这种思路为“就事论事”的思路。具体而言,保留思路一的外循环,每一次都进行0-1判断,若为1,则意味着连续“1”序列在当前还未结束,将计数变量加1;若为0,代表着连续“1”序列的结束,则将计数变量与最大值比较进行取舍,同时将计数变量重置。这个算法比起思路一在代码阅读上更容易,也更容易理解一下。代码如下:

class Solution {
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
        int s = nums.size();
        int count = 0, max = 0;
        for (int i = 0; i < s; i++){
            if(nums[i] == 0){                             // 为0时,count(计数变量)与max(最大值)比较从而进行取舍
                if (count > max){
                    max = count;
                }
                count = 0;                                  // 重置计数变量
            }
            else{                                              // 为1时,计数变量加1
                count++;
            }
        }
        if(count > max)                                  // 这一个判断是针对序列最后一位为1的情况,比如{0,1,1}的序列,在序列循环检索结束时,最后一个连续“1”序列并没有统计,会对结果造成很大的影响
        max = count;                                   
        return max;
    }
};

根据leetcode的回馈,思路二花费的时间比思路一更长,我判断是在类似{1,0,0}中连续的“0”处浪费了时间。

思路二,完结。

第三种思路算是思路二的一种变形,最大的改变是改变了计数变量与最大值比较的位置,即在每一次判断为“1”进行计数变量加1时进行比较。这是我看到leetcode的讨论区中xiaobooluo发布的代码,此处引用:

class Solution {
public:
int findMaxConsecutiveOnes(vector<int>& nums) {
int max=0,cur=0;
for(int i=0;i<nums.size();i++)
{
if(nums[i]&1)
{
max=max>++cur?max:cur;                          //区别所在
}
else cur=0;
}
return max;
}
};

区别就是关于max的处理,xiaobooluo在计数变量加1时进行max的处理。根据反馈,这种思路比思路二要快一些。我认为这种算法在面对多个“1”连续的情况时会花费更多的时间,比如{1,0,1,1,1,1,1},因为此时比较的次数会大量增加。

思路三,完结。

总的来说,我认为思路二和思路三都存在一定程度上无用操作(分别为多个0连续和数量超过max的多个1连续)。所以个人更偏向于改良后的思路一。

学识疏浅,如有不足,还望读者不吝赐教,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值