文章目录
- 题目描述
- 思路分析
- 完整代码
题目描述
思路分析
这道题我读了一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边一边,不是很懂。。。。。。。。。
于是摸索着做,
再离谱点?
又重新去看了看题,想了半天,实际上这道题不难,思路也很简单,就是我没看懂题 属是有点蠢。
简单来说:题目所给的数组是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