leetcode(力扣) 393. UTF-8 编码验证 (没看懂题导致的一页红)

题目描述

给定一个表示数据的整数数组 data ,返回它是否为有效的 UTF-8 编码。
UTF-8 中的一个字符可能的长度为 1 到 4 字节,遵循以下的规则:
对于 1 字节 的字符,字节的第一位设为 0 ,后面 7 位为这个符号的 unicode 码。
对于 n 字节 的字符 (n > 1),第一个字节的前 n 位都设为1,第 n+1 位设为 0 ,后面字节的前两位一律设为 10 。剩下的没有提及的二进制位,全部为这个符号的 unicode 码。
这是 UTF-8 编码的工作方式:
在这里插入图片描述
注意:输入是整数数组。只有每个整数的 最低 8 个有效位 用来存储数据。这意味着每个整数只表示 1 字节的数据。

示例 1:
输入:data = [197,130,1]
输出:true
解释:数据表示字节序列:11000101 10000010 00000001。
这是有效的 utf-8 编码,为一个 2 字节字符,跟着一个 1 字节字符。

示例 2:
输入:data = [235,140,4]
输出:false
解释:数据表示 8 位的序列: 11101011 10001100 00000100.
前 3 位都是 1 ,第 4 位为 0 表示它是一个 3 字节字符。
下一个字节是开头为 10 的延续字节,这是正确的。
但第二个延续字节不以 10 开头,所以是不符合规则的。

思路分析

这道题我读了一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边,不是很懂。。。。。。。。。

于是摸索着做,在这里插入图片描述
再离谱点?

又重新去看了看题,想了半天,实际上这道题不难,思路也很简单,就是我没看懂题 属是有点蠢。

简单来说:题目所给的数组是int型,数值是多少无关紧要。先全部转换成8位二进制。

转为二进制之后 只有几下几种情况:

  • 0XXXXXXX (一字节)
  • 10XXXXXX
  • 110XXXXX (二字节)
  • 1110XXXX (三字节)
  • 11110XXX (四字节)

若为一字节 0XXXXXXX 的形式,则无视。
若为二字节 110XXXXX 的形式,则后续需要跟一个10XXXXXX。
若为三字节 1110XXXX 的形式,则后续需要跟二个10XXXXXX。
若为四字节 11110XXX 的形式,则后续需要跟三个10XXXXXX。

也就是说 N字节 后续需要跟 N-1个 10XXXXXX。

比如 所给的示例:[197,130,1]
首先转换为二进制: 11000101 10000010 00000001。
第一个为110XXXXX ,二字节,则要求后面要跟一个10XXXXXX, ,而所给的第二个刚好是 10开头的。符合要求。继续,第三个是0开头的,无视。故该示例True。

第二个示例:[235,140,4]
转为二进制, 11101011 10001100 00000100.

第一个是1110XXXX, 则后续需要跟两个10XXXXXX。而题目所给的第二个是10开头,第三个是0开头的,并不是10开头的,所以没有满足 直接返回False。

所以开始说的那个条件,遇到0开头直接无视,这里的无视是又条件的无视,满足了前方需要的10XXXXXX的个数时,才能无视。若10XXXXXX的个数没有得到满足而出现了0开头的数,则直接False。

思路就简单了。

  • 全部转换成二进制存起来放到temp里
  • 遍历temp,判断当前是哪一个情况开头的,如果是0则指针往后移。
  • 若为 110 、1110、11110、则对应看他后面是否跟着相应数量的 10XXXXXX, 若个数符合 ,则指针相应后移 2 ,3 ,4。

完整代码

class Solution:
    def validUtf8(self, data: List[int]) -> bool:
        def continuous(idx,num):
            for i in range(idx+1,idx+num+1):
                if data[i][:2] != '10':
                    return False
            return True


        for i in range(len(data)): # 全变成二进制
            data[i] = "{:08b}".format(data[i])

        p = 0
        while p < len(data):
            if data[p][0] == '0':
                p +=1
            elif data[p][:3] == '110' and p+1 < len(data):
                if not continuous(p,1):
                    return False
                p +=2
            elif data[p][:4] == '1110' and p+2 < len(data):
                if not continuous(p,2):
                    return False
                p +=3
            elif data[p][:5] == '11110' and p+3 < len(data):
                if not continuous(p,3):
                    return False
                p +=4
            else:
                return False
        return True
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深度不学习!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值