数组中连续元素的个数:Leetcode 485, Leetcode 443

Leetcode 485. 最大连续 1 的个数 这道题给定一个二进制数组(元素取值只有 1 和 0),要求计算其中最大连续 1 的个数。

Leetcode 485 思路

设置 count 来记录当前连续 1 的个数,max_ count 用于保存最大连续 1 的个数。当遇到更大的 count 值时,更新 max_count,最后返回 max_count。

两种实现方法

方法一、遇到 0 时更新 max_count

遍历数组:

如果元素是 1,count + 1;

如果元素是 0,(1) 比较 count 与 max_count,取其中较大值更新 max_ count ;(2) 重置 count 为 0。

这样还不够,循环结束后还要记得更新一次 max_count 。为什么呢?因为只有元素是 0 时才会更新 max_count,如果数组末尾是一串连续 1,那么最后一次的 count 还没有用于更新 max_count。例如,我一开始就没有写这个,导致示例 1 都没有运行通过,nums = [1,1,0,1,1,1],正确输出是 3,而我的代码运行后输出是 2,就是因为没有使用最后连续 3 个 1 的 count = 3 更新 max_count。

Python 代码为:

class Solution:
    def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
        count, max_count= 0, 0
        for num in nums:
            if num:
                count += 1                
            else:
                max_count = max(count, max_count)                
                count = 0
                
        max_count = max(count, max_count)
        return max_count                 

但是新手容易忘记最后一次比较和更新 max_count,也可以改成元素为 1 时更新 max_count:

方法二、遇到 1 时更新 max_count

遍历数组:

如果元素是 1,(1) count + 1;(2) 比较 count 与 max_count,取较大值更新 max_ count。

如果元素是 0,重置 count 为 0。

Python 代码为:

class Solution:
    def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
        count, max_count= 0, 0
        for num in nums:
            if num:
                count += 1
                max_count = max(count, max_count)
            else:               
                count = 0
        return max_count           

拓展

把前面介绍的方法一思路提炼一下,可以总结为:

初始化参数:计数(count),
遍历数组元素:
    if 该元素是连续元素:
        count + 1
    else:
        保存连续元素记录
        更新为新元素,重置计数
处理数组末尾的连续字符(重复一遍else部分保存连续元素记录的操作)  

运用这一思路,会发现 Leetcode 443. 压缩字符串 与刚才解决的 Leetcode 485. 最大连续 1 的个数 有相似之处。 Leetcode 443 给出了一个字符数组,要对其进行压缩。采用的方法是把 连续的同一字符 压缩成“字符 + 长度”的表示,例如:chars = [“a”,“a”,“b”,“b”,“c”,“c”,“c”],压缩后变成 [“a”,“2”,“b”,“2”,“c”,“3”]。这也需要统计连续字符的个数。

有两种情况需要注意:

  • 如果这个字符只有 1 个,就只写这个字符,后面不写长度,例如 chars = [“a”],压缩后变成 [“a”] 。
  • 如果连续字符的个数大于 9,例如,有 10 个 “a”,压缩后应该表示为 [“a”,“1”,“0”]。

这道题还要求直接修改原数组,返回结果为新数组的长度。这就要用到快慢双指针,快指针用于遍历数组(读取操作),统计连续字符数;慢指针用于修改原数组得到压缩数组(写入操作)。虽然这两个指针是在同一个数组上操作,但由于慢指针写的速度不会快于快指针读的速度,因此可以修改原数组得到压缩数组。

Leetcode 443 思路

初始化参数:快慢指针均指向 chars[0],计数(count=1)。

(快指针)从chars[1]开始,遍历数组:
    if 快指针与慢指针的字符相同,说明是连续字符:
        count + 1
    else:
        # 添加慢指针指向的连续字符长度
        1.如果连续字符长度(count)大于1,要添加该长度到压缩数组(慢指针)
        
        # 添加快指针指向的新字符
        2.添加新字符到压缩数组(慢指针)  
        3.重置 count

处理数组末尾的连续字符:
(使用else部分的“添加慢指针指向的连续字符长度”)
1.如果连续字符长度(count)大于1,要添加该长度到压缩数组(慢指针)

返回值:慢指针

代码实现

Python代码为:

class Solution:
    def compress(self, chars: List[str]) -> int:
        slow, count = 0, 1
        
        for fast in range(1, len(chars)):
            # 如果是连续字符
            if chars[fast] == chars[slow]:
                count += 1

            else:
                # 添加慢指针指向的连续字符长度
                if count > 1:
                    count_str = str(count)
                    for i in range(len(count_str)):
                        slow += 1
                        chars[slow] = count_str[i]                    

                # 添加快指针指向的新字符
                slow += 1
                chars[slow] = chars[fast]

                # 重置计数
                count = 1
        
        # 处理数组末尾的连续字符
        # 添加慢指针指向的连续字符长度
        if count > 1:
            count_str = str(count)
            for i in range(len(count_str)):
                slow += 1
                chars[slow] = count_str[i] 
        
        return slow+1
        

本文对您有帮助的话,请点赞支持一下吧,谢谢!

关注我 宁萌Julie,互相学习,多多交流呀!

参考:

Simple Python - Max Consecutive Ones - LeetCode

你可能感兴趣的:(Leetcode学习笔记,leetcode,算法,python,数据结构)