思路:位运算
- 不要转化成字符串去判断,反复折磨,没必要
 - 位运算是最正的解法
 - 此题的逻辑是比较复杂的,可以分成几步来进行 
- 判断当前int的前缀情况,如果是0,说明是1字节的字符;如果有n个
1,说明其后有 n - 1 个后续位置(往后读 n - 1 个 int) - 对于后面的 n - 1 个后续位置,分别检查是不是
10开头的,是10开头,就说明符合,否则不符合,返回false - 如果一直能读到最后一个位置,说明整个序列没问题,否则有错
 
 - 判断当前int的前缀情况,如果是0,说明是1字节的字符;如果有n个
 关于位运算有两点:
class Solution:"""此题的逻辑是比较复杂的,可以分成几步来进行1. 判断当前int的前缀情况,如果是0,说明是1字节的字符;如果有n个1,说明其后有 n - 1 个后续位置(往后读 n - 1 个 int)2. 对于后面的 n - 1 个后续位置,分别检查是不是10开头的,是10开头,就说明符合,否则不符合,返回false3. 如果一直能读到最后一个位置,说明整个序列没问题,否则有错关于位运算有两点:1. 利用mask1去读有几个前缀的12. 利用mask1 和 mask2 去判断是不是10开头的"""def validUtf8(self, data: List[int]) -> bool:mask1 = (1 << 7)mask2 = (1 << 7) + (1 << 6) - 1len_data = len(data)def getDistance(cur_num: int) -> int:# 说明第一位是0if (cur_num & mask1) == 0:return 0# 如果不是0distance = 0while (cur_num & mask1) == mask1:cur_num <<= 1distance += 1return distance if 2 <= distance <= 4 else -1def checkPrefix(cur_num: int) -> bool:return (cur_num & mask1 == mask1) and (cur_num | mask2 == mask2)begin_pos = 0while begin_pos < len_data:next_dis = getDistance(data[begin_pos])if next_dis == 0:begin_pos += 1elif next_dis == -1:return Falseelse:if begin_pos + next_dis > len_data:return Falsefor i in range(begin_pos + 1, begin_pos + next_dis):if not checkPrefix(data[i]):return Falsebegin_pos += next_disreturn True
