LeetCode 393. UTF-8 编码验证 / 599. 两个列表的最小索引总和 / 2044. 统计按位或能得到最大值的子集数目

Posted Zephyr丶J

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 393. UTF-8 编码验证 / 599. 两个列表的最小索引总和 / 2044. 统计按位或能得到最大值的子集数目相关的知识,希望对你有一定的参考价值。

393. UTF-8 编码验证

2022.3.13 每日一题

题目描述

给定一个表示数据的整数数组 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 编码的工作方式:

   Char. number range  |        UTF-8 octet sequence
      (hexadecimal)    |              (binary)
   --------------------+---------------------------------------------
   0000 0000-0000 007F | 0xxxxxxx
   0000 0080-0000 07FF | 110xxxxx 10xxxxxx
   0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
   0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

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

提示:

1 <= data.length <= 2 * 10^4
0 <= data[i] <= 255

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/utf-8-validation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

按照所给规律判断就行了

class Solution 
    public boolean validUtf8(int[] data) 
        //看例子得到这个数组表示的字符可能不只是一个,可能是多个
        //然后怎么判断呢,其实挨个判断就可以了
        //如果开头是0,那么这个字符只有一个字节,可行,跳过
        //如果开头有四个1以上或者只有1个1,直接false
        //如果有两个到四个1,那么就看后面两个到四个数,是否开头都是10,不是的话false

        int n = data.length;
        int count = 0;
        for(int i = 0; i < n; i++)
            int num = data[i];
            //如果是后面的字节,但是前两个位置不是10,那么直接false
            if(count > 0)
                if((num >> 6) != 2)
                    return false;
                else
                    count--;
            //如果开头是0,那么是单字节
            else if((num >> 7) == 0)
                continue;
            //如果有4个以上的1或者1个1,那么false
            else if((num >> 3) > 30 || (num >> 6) == 2)
                return false;
            else if((num >> 5) == 6)
                count = 1;
            else if((num >> 4) == 14)
                count = 2;
            else if((num >> 3) == 30)
                count = 3;
        
        return count == 0 ? true : false;
    

599. 两个列表的最小索引总和

2022.3.14 每日一题

题目描述

假设 Andy 和 Doris 想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示。

你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅。 如果答案不止一个,则输出所有答案并且不考虑顺序。 你可以假设答案总是存在。

示例 1:

输入: list1 = [“Shogun”, “Tapioca Express”, “Burger King”, “KFC”],list2 = [“Piatti”, “The Grill at Torrey Pines”, “Hungry Hunter Steakhouse”, “Shogun”]
输出: [“Shogun”]
解释: 他们唯一共同喜爱的餐厅是“Shogun”。

示例 2:

输入:list1 = [“Shogun”, “Tapioca Express”, “Burger King”, “KFC”],list2 = [“KFC”, “Shogun”, “Burger King”]
输出: [“Shogun”]
解释: 他们共同喜爱且具有最小索引和的餐厅是“Shogun”,它有最小的索引和1(0+1)。

提示:

1 <= list1.length, list2.length <= 1000
1 <= list1[i].length, list2[i].length <= 30
list1[i] 和 list2[i] 由空格 ’ ’ 和英文字母组成。
list1 的所有字符串都是 唯一 的。
list2 中的所有字符串都是 唯一 的。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-index-sum-of-two-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

我本以为我这种方法是高效方法,没想到反而低了
还不如用哈希表

class Solution 
    public String[] findRestaurant(String[] list1, String[] list2) 
        int l1 = list1.length;
        int l2 = list2.length;
        int max = l1 - 1 + l2 - 1;
        List<String> list = new ArrayList<>();
        for(int i = 0; i <= max; i++)
            for(int first = 0; first <= i && first < l1; first++)
                if(i - first < l2 && list1[first].equals(list2[i - first]))
                    list.add(list1[first]);
            
            if(list.size() > 0)
                break;
        
        return list.toArray(new String[0]);
    

2044. 统计按位或能得到最大值的子集数目

2022.3.15 每日一题

题目描述

给你一个整数数组 nums ,请你找出 nums 子集 按位或 可能得到的 最大值 ,并返回按位或能得到最大值的 不同非空子集的数目 。

如果数组 a 可以由数组 b 删除一些元素(或不删除)得到,则认为数组 a 是数组 b 的一个 子集 。如果选中的元素下标位置不一样,则认为两个子集 不同 。

对数组 a 执行 按位或 ,结果等于 a[0] OR a[1] OR … OR a[a.length - 1](下标从 0 开始)。

示例 1:

输入:nums = [3,1]
输出:2
解释:子集按位或能得到的最大值是 3 。有 2 个子集按位或可以得到 3 :
-[3]
-[3,1]

示例 2:

输入:nums = [2,2,2]
输出:7
解释:[2,2,2] 的所有非空子集的按位或都可以得到 2 。总共有 23 - 1 = 7 个子集。

示例 3:

输入:nums = [3,2,1,5]
输出:6
解释:子集按位或可能的最大值是 7 。有 6 个子集按位或可以得到 7 :
-[3,5]
-[3,1,5]
-[3,2,5]
-[3,2,1,5]
-[2,5]
-[2,1,5]

提示:

1 <= nums.length <= 16
1 <= nums[i] <= 10^5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-number-of-maximum-bitwise-or-subsets
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

class Solution 
    public int countMaxOrSubsets(int[] nums) 
        //因为或是有1就是1,所以先统计每个数哪些数位是1
        //每个位置都有一个数肯定是最大的,但是有重复的好像不太好处理
        //那么只能回溯或者状压了

        int n = nums.length;
        int max = 0;
        int count = 0;

        int mask = 1 << n;
        for(int i = 1; i < mask; i++)
            int temp = 0;
            for(int j = 0; j < n; j++)
                if(((i >> j) & 1) == 1)
                    temp |= nums[j];
                
            
            if(temp > max)
                max = temp;
                count = 1;
            else if(temp == max)
                count++;
        
        return count;
    

以上是关于LeetCode 393. UTF-8 编码验证 / 599. 两个列表的最小索引总和 / 2044. 统计按位或能得到最大值的子集数目的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 393. UTF-8 Validation

[LeetCode] UTF-8 Validation 编码验证

java 393. UTF-8 Validation.java

java 393. UTF-8 Validation.java

java 393. UTF-8 Validation.java

java 393. UTF-8 Validation.java