列表

详情


393. UTF-8 编码验证

给定一个表示数据的整数数组 data ,返回它是否为有效的 UTF-8 编码。

UTF-8 中的一个字符可能的长度为 1 到 4 字节,遵循以下的规则:

  1. 对于 1 字节 的字符,字节的第一位设为 0 ,后面 7 位为这个符号的 unicode 码。
  2. 对于 n 字节 的字符 (n > 1),第一个字节的前 n 位都设为1,第 n+1 位设为 0 ,后面字节的前两位一律设为 10 。剩下的没有提及的二进制位,全部为这个符号的 unicode 码。

这是 UTF-8 编码的工作方式:

      Number of Bytes  |        UTF-8 octet sequence
                       |              (binary)
   --------------------+---------------------------------------------
            1          | 0xxxxxxx
            2          | 110xxxxx 10xxxxxx
            3          | 1110xxxx 10xxxxxx 10xxxxxx
            4          | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

x 表示二进制形式的一位,可以是 0 或 1

注意:输入是整数数组。只有每个整数的 最低 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 开头,所以是不符合规则的。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: bool validUtf8(vector<int>& data) { } };

java 解法, 执行用时: 2 ms, 内存消耗: 42.2 MB, 提交时间: 2023-02-27 14:38:00

class Solution {
    private static final int ONE = 1 << 7, TWO = ONE + (1 << 6);
    public boolean validUtf8(int[] data) {
        for(int i = 0; i < data.length;) {
            int l = 1;
            for(; l < 7 && ((data[i] >> (8 - l)) & 1) == 1; l++) {}
            if(l == 2 || l > 5 || i + l - 2 >= data.length)
                return false;
            if(l > 2) l--;
            for(int j = i + 1; j < i + l; j++)
                if((data[j] & TWO) != ONE)
                    return false;
            i += l;
        }
        return true;
    }
}

javascript 解法, 执行用时: 84 ms, 内存消耗: 41.7 MB, 提交时间: 2023-02-27 14:37:42

/**
 * @param {number[]} data
 * @return {boolean}
 */
const ONE = 1 << 7, TWO = ONE + (1 << 6)
var validUtf8 = function(data) {
    for(let i = 0; i < data.length; ) {
        let l = 1
        for(;l < 7 && (data[i] >> (8 - l)) & 1 == 1; l++) {}
        if(l == 2 || l > 5 || i + l - 2 >= data.length)
            return false
        if(l > 2)
            l--
        for(let j = i + 1; j < i + l; j++)
            if((data[j] & TWO) != ONE)
                return false
        i += l
    }
    return true
};

python3 解法, 执行用时: 36 ms, 内存消耗: 15.2 MB, 提交时间: 2023-02-27 14:37:25

ONE = 1 << 7
TWO = ONE + (1 << 6)

class Solution:
    def validUtf8(self, data: List[int]) -> bool:
        i = 0
        while i < len(data):
            l = 1
            while l < 7 and data[i] >> (8 - l) & 1:
                l += 1
            if l == 2 or l > 5:
                return False
            if l > 2:
                l -= 1
            if i + l - 1 >= len(data):
                return False
            for j in range(i + 1, i + l):
                if (data[j] & TWO) != ONE:
                    return False
            i += l
        return True

golang 解法, 执行用时: 12 ms, 内存消耗: 5 MB, 提交时间: 2023-02-27 14:37:02

const one int = 1 << 7
const two int = one + (1 << 6)
func validUtf8(data []int) bool {
    for i := 0; i < len(data); {
        l := 1
        for l < 7 && (data[i] >> (8 - l)) & 1 == 1 {
            l++            
        }
        if l == 2 || l > 5 || i + l - 2 >= len(data) {
            return false
        }
        if l > 2 {
            l--
        }
        for j := i + 1; j < i + l; j++ {
            if data[j] & two != one {
                return false
            }
        }
        i += l
    }
    return true
}

golang 解法, 执行用时: 12 ms, 内存消耗: 5 MB, 提交时间: 2023-02-27 14:36:45

const mask1, mask2 = 1 << 7, 1<<7 | 1<<6

func getBytes(num int) int {
    if num&mask1 == 0 {
        return 1
    }
    n := 0
    for mask := mask1; num&mask != 0; mask >>= 1 {
        n++
        if n > 4 {
            return -1
        }
    }
    if n >= 2 {
        return n
    }
    return -1
}

func validUtf8(data []int) bool {
    for index, m := 0, len(data); index < m; {
        n := getBytes(data[index])
        if n < 0 || index+n > m {
            return false
        }
        for _, ch := range data[index+1 : index+n] {
            if ch&mask2 != mask1 {
                return false
            }
        }
        index += n
    }
    return true
}

python3 解法, 执行用时: 60 ms, 内存消耗: 15.2 MB, 提交时间: 2023-02-27 14:36:29

class Solution:
    def validUtf8(self, data: List[int]) -> bool:
        MASK1, MASK2 = 1 << 7, (1 << 7) | (1 << 6)

        def getBytes(num: int) -> int:
            if (num & MASK1) == 0:
                return 1
            n, mask = 0, MASK1
            while num & mask:
                n += 1
                if n > 4:
                    return -1
                mask >>= 1
            return n if n >= 2 else -1

        index, m = 0, len(data)
        while index < m:
            n = getBytes(data[index])
            if n < 0 or index + n > m or any((ch & MASK2) != MASK1 for ch in data[index + 1: index + n]):
                return False
            index += n
        return True

上一题