leetcode 393. UTF-8 Validation :
- 就是根据第一个byte分类讨论:
- 先读取第一个int,然后分析是哪种编码情况
- 根据不同情况分析剩余相关int编码是否合法?继续解析剩下的data[n:] : return False
#393. UTF-8 Validation
class Solution(object):
def validUtf8(self, data):
"""
:type data: List[int]
:rtype: bool
"""
while len(data):
i=0
if (data[i]&0b11110000)==0xF0: # 第四种情况
if (len(data)<4): return False
for j in xrange(1,4): # 检查剩余的3个数字
if data[j]&(0b10<<6)!=(0b10<<6):
return False
data=data[4:] # del data[0:3]
if len(data)==0: # all pass,return True
return True
else:
continue
# return self.validUtf8(data[4:]) # 递归在大规模会超时 还是剔除好 线性简洁明了
elif data[i]&(0b1110<<4)==(0b1110<<4): # 第三种情况 同上
if (len(data)<3): return False
for j in xrange(1,3): # check data[1],data[2]
if data[j]&(0b10<<6)!=(0b10<<6):
return False
data = data[3:] # del data[0:2]
if len(data)==0:
return True
continue
# return self.validUtf8(data[3:])
elif data[i]&(0b1100<<4)==(0b1100<<4): # 第二种情况
if (len(data)<2): return False
for j in xrange(1,2):
if data[j]&(0b10<<6)!=(0b10<<6):
return False
data = data[2:]
if len(data)==0:
return True
continue
# return self.validUtf8(data[2:])
elif (data[i]>>7)&1==0: # 第二种情况
data=data[1:]
if len(data)==0:
return True
continue
# return self.validUtf8(data[1:])
return False
if __name__ =='__main__':
a= Solution()
print a.validUtf8([197,130,1])
print a.validUtf8([235,140,4])
遇到的问题:
开始用递归 当data[]规模很大的时候就会超时。所以采用data=data[n:]来弃掉前面已经检验的字符。
但是当前面的数字是合法的,那么继续往后解析时,i的取值返回还是按照初始的len(data),并没有动态地缩短,导致data[i]超出范围。
for i in xrange(0,len(data)):
#这个for循环会出问题,就是当data=data[n:]后,i取值范围不变
if (data[i]&0b11110000)==0xF0:
if (len(data)<4): return False
for j in xrange(1,4):
if data[j]&(0b10<<6)!=(0b10<<6):
return False
data=data[4:]
if len(data)==0:
return True
else:
continue
# return self.validUtf8(data[4:]) # 递归会超时
... ...
改成while就好了:
while len(data): # 此时len(data)是实时更新的
i=0
if (data[i]&0b11110000)==0xF0:
if (len(data)<4): return False
... ...