• 周赛371(模拟、哈希+排序+枚举)


    周赛371

    2932. 找出强数对的最大异或值 I

    简单

    给你一个下标从 0 开始的整数数组 nums 。如果一对整数 xy 满足以下条件,则称其为 强数对

    • |x - y| <= min(x, y)

    你需要从 nums 中选出两个整数,且满足:这两个整数可以形成一个强数对,并且它们的按位异或(XOR)值是在该数组所有强数对中的 最大值

    返回数组 nums 所有可能的强数对中的 最大 异或值。

    注意,你可以选择同一个整数两次来形成一个强数对。

    示例 1:

    输入:nums = [1,2,3,4,5]
    输出:7
    解释:数组 nums 中有 11 个强数对:(1, 1), (1, 2), (2, 2), (2, 3), (2, 4), (3, 3), (3, 4), (3, 5), (4, 4), (4, 5) 和 (5, 5) 。
    这些强数对中的最大异或值是 3 XOR 4 = 7 。
    
    • 1
    • 2
    • 3
    • 4

    示例 2:

    输入:nums = [10,100]
    输出:0
    解释:数组 nums 中有 2 个强数对:(10, 10) 和 (100, 100) 。
    这些强数对中的最大异或值是 10 XOR 10 = 0 ,数对 (100, 100) 的异或值也是 100 XOR 100 = 0 。
    
    • 1
    • 2
    • 3
    • 4

    示例 3:

    输入:nums = [5,6,25,30]
    输出:7
    解释:数组 nums 中有 6 个强数对:(5, 5), (5, 6), (6, 6), (25, 25), (25, 30) 和 (30, 30) 。
    这些强数对中的最大异或值是 25 XOR 30 = 7 ;另一个异或值非零的数对是 (5, 6) ,其异或值是 5 XOR 6 = 3 。
    
    • 1
    • 2
    • 3
    • 4

    提示:

    • 1 <= nums.length <= 50
    • 1 <= nums[i] <= 100

    模拟

    class Solution {
        public int maximumStrongPairXor(int[] nums) {
            int res = 0, n = nums.length;
            for(int i = 0; i < n; i++){
                for(int j = i; j < n; j++){
                    if(Math.abs(nums[i] - nums[j]) <= Math.min(nums[i], nums[j]))
                        res = Math.max(res, nums[i] ^ nums[j]);
                }
            }
            return res;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2933. 高访问员工

    中等

    给你一个长度为 n 、下标从 0 开始的二维字符串数组 access_times 。对于每个 i0 <= i <= n - 1 ),access_times[i][0] 表示某位员工的姓名,access_times[i][1] 表示该员工的访问时间。access_times 中的所有条目都发生在同一天内。

    访问时间用 四位 数字表示, 符合 24 小时制 ,例如 "0800""2250"

    如果员工在 同一小时内 访问系统 三次或更多 ,则称其为 高访问 员工。

    时间间隔正好相差一小时的时间 被视为同一小时内。例如,"0815""0915" 不属于同一小时内。

    一天开始和结束时的访问时间不被计算为同一小时内。例如,"0005""2350" 不属于同一小时内。

    以列表形式,按任意顺序,返回所有 高访问 员工的姓名。

    示例 1:

    输入:access_times = [["a","0549"],["b","0457"],["a","0532"],["a","0621"],["b","0540"]]
    输出:["a"]
    解释:"a" 在时间段 [05:32, 06:31] 内有三条访问记录,时间分别为 05:32 、05:49 和 06:21 。
    但是 "b" 的访问记录只有两条。
    因此,答案是 ["a"] 。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    示例 2:

    输入:access_times = [["d","0002"],["c","0808"],["c","0829"],["e","0215"],["d","1508"],["d","1444"],["d","1410"],["c","0809"]]
    输出:["c","d"]
    解释:"c" 在时间段 [08:08, 09:07] 内有三条访问记录,时间分别为 08:08 、08:09 和 08:29 。
    "d" 在时间段 [14:10, 15:09] 内有三条访问记录,时间分别为 14:10 、14:44 和 15:08 。
    然而,"e" 只有一条访问记录,因此不能包含在答案中,最终答案是 ["c","d"] 。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    示例 3:

    输入:access_times = [["cd","1025"],["ab","1025"],["cd","1046"],["cd","1055"],["ab","1124"],["ab","1120"]]
    输出:["ab","cd"]
    解释:"ab"在时间段 [10:25, 11:24] 内有三条访问记录,时间分别为 10:25 、11:20 和 11:24 。
    "cd" 在时间段 [10:25, 11:24] 内有三条访问记录,时间分别为 10:25 、10:46 和 10:55 。
    因此,答案是 ["ab","cd"] 。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    提示:

    • 1 <= access_times.length <= 100
    • access_times[i].length == 2
    • 1 <= access_times[i][0].length <= 10
    • access_times[i][0] 仅由小写英文字母组成。
    • access_times[i][1].length == 4
    • access_times[i][1] 采用24小时制表示时间。
    • access_times[i][1] 仅由数字 '0''9' 组成。

    哈希 + 分组排序 + 枚举

    class Solution {
        public List<String> findHighAccessEmployees(List<List<String>> access_times) {
            Map<String, List<String>> map = new HashMap<>();
            for(List<String> at : access_times){
                if(!map.containsKey(at.get(0)))
                    map.put(at.get(0), new ArrayList<>());
                map.get(at.get(0)).add(at.get(1));
            }
            List<String> res = new ArrayList<>();
            for(Map.Entry<String, List<String>> entry : map.entrySet()){
                List<String> times = entry.getValue();
                if(times.size() < 3) continue;
                Collections.sort(times);
                boolean flag = false;
                for(int j = 2; j < times.size(); j++){
                    if(Integer.valueOf(times.get(j)) - Integer.valueOf(times.get(j-2)) < 100){
                        flag = true;
                        break;
                    }
                }
                if(flag) res.add(entry.getKey());
            }
            return res;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    2934. 最大化数组末位元素的最少操作次数

    中等

    给你两个下标从 0 开始的整数数组 nums1nums2 ,这两个数组的长度都是 n

    你可以执行一系列 操作(可能不执行)

    在每次操作中,你可以选择一个在范围 [0, n - 1] 内的下标 i ,并交换 nums1[i]nums2[i] 的值。

    你的任务是找到满足以下条件所需的 最小 操作次数:

    • nums1[n - 1] 等于 nums1 中所有元素的 最大值 ,即 nums1[n - 1] = max(nums1[0], nums1[1], ..., nums1[n - 1])
    • nums2[n - 1] 等于 nums2 中所有元素的 最大值 ,即 nums2[n - 1] = max(nums2[0], nums2[1], ..., nums2[n - 1])

    以整数形式,表示并返回满足上述 全部 条件所需的 最小 操作次数,如果无法同时满足两个条件,则返回 -1

    示例 1:

    输入:nums1 = [1,2,7],nums2 = [4,5,3]
    输出:1
    解释:在这个示例中,可以选择下标 i = 2 执行一次操作。
    交换 nums1[2] 和 nums2[2] 的值,nums1 变为 [1,2,3] ,nums2 变为 [4,5,7] 。
    同时满足两个条件。
    可以证明,需要执行的最小操作次数为 1 。
    因此,答案是 1 。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    示例 2:

    输入:nums1 = [2,3,4,5,9],nums2 = [8,8,4,4,4]
    输出:2
    解释:在这个示例中,可以执行以下操作:
    首先,选择下标 i = 4 执行操作。
    交换 nums1[4] 和 nums2[4] 的值,nums1 变为 [2,3,4,5,4] ,nums2 变为 [8,8,4,4,9] 。
    然后,选择下标 i = 3 执行操作。
    交换 nums1[3] 和 nums2[3] 的值,nums1 变为 [2,3,4,4,4] ,nums2 变为 [8,8,4,5,9] 。
    同时满足两个条件。 
    可以证明,需要执行的最小操作次数为 2 。 
    因此,答案是 2 。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    示例 3:

    输入:nums1 = [1,5,4],nums2 = [2,5,3]
    输出:-1
    解释:在这个示例中,无法同时满足两个条件。
    因此,答案是 -1 。
    
    • 1
    • 2
    • 3
    • 4

    提示:

    • 1 <= n == nums1.length == nums2.length <= 1000
    • 1 <= nums1[i] <= 109
    • 1 <= nums2[i] <= 109

    枚举(脑筋急转弯)

    class Solution {
        /**
        答案只有两种情况,末尾元素交换和不交换,枚举两种情况
    
        什么时候需要交换? 当 nums[i] 元素大于 末尾元素 时,一定需要交换 
         */
        public int minOperations(int[] nums1, int[] nums2) {
            int n = nums1.length;
            int cnt = Math.min(f(nums1, nums2, nums1[n-1], nums2[n-1]),
                f(nums1, nums2, nums2[n-1], nums1[n-1]) + 1);
            if(cnt >= Integer.MAX_VALUE / 2) 
                return -1;
            return cnt;
        }
    
        public int f(int[] nums1, int[] nums2, int mx1, int mx2){
            int n = nums1.length - 1;
            int cnt = 0;
            for(int i = 0; i < n; i++){
                if(nums1[i] <= mx1 && nums2[i] <= mx2)
                    continue;
                if(nums1[i] <= mx2 && nums2[i] <= mx1)
                    cnt += 1;
                else return Integer.MAX_VALUE / 2;
            }
            return cnt;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    2935. 找出强数对的最大异或值 II

    困难

    给你一个下标从 0 开始的整数数组 nums 。如果一对整数 xy 满足以下条件,则称其为 强数对

    • |x - y| <= min(x, y)

    你需要从 nums 中选出两个整数,且满足:这两个整数可以形成一个强数对,并且它们的按位异或(XOR)值是在该数组所有强数对中的 最大值

    返回数组 nums 所有可能的强数对中的 最大 异或值。

    注意,你可以选择同一个整数两次来形成一个强数对。

    示例 1:

    输入:nums = [1,2,3,4,5]
    输出:7
    解释:数组 nums 中有 11 个强数对:(1, 1), (1, 2), (2, 2), (2, 3), (2, 4), (3, 3), (3, 4), (3, 5), (4, 4), (4, 5) 和 (5, 5) 。
    这些强数对中的最大异或值是 3 XOR 4 = 7 。
    
    • 1
    • 2
    • 3
    • 4

    示例 2:

    输入:nums = [10,100]
    输出:0
    解释:数组 nums 中有 2 个强数对:(10, 10) 和 (100, 100) 。
    这些强数对中的最大异或值是 10 XOR 10 = 0 ,数对 (100, 100) 的异或值也是 100 XOR 100 = 0 。
    
    • 1
    • 2
    • 3
    • 4

    示例 3:

    输入:nums = [500,520,2500,3000]
    输出:1020
    解释:数组 nums 中有 6 个强数对:(500, 500), (500, 520), (520, 520), (2500, 2500), (2500, 3000) 和 (3000, 3000) 。
    这些强数对中的最大异或值是 500 XOR 520 = 1020 ;另一个异或值非零的数对是 (5, 6) ,其异或值是 2500 XOR 3000 = 636 。
    
    • 1
    • 2
    • 3
    • 4

    提示:

    • 1 <= nums.length <= 5 * 104
    • 1 <= nums[i] <= 220 - 1

    哈希表

    https://leetcode.cn/problems/maximum-strong-pair-xor-ii/solutions/2523213/0-1-trie-hua-dong-chuang-kou-pythonjavac-gvv2/

    class Solution {
        public int maximumStrongPairXor(int[] nums) {
            Arrays.sort(nums);
            int highBit = 31 - Integer.numberOfLeadingZeros(nums[nums.length - 1]);
    
            int ans = 0, mask = 0;
            Map<Integer, Integer> mp = new HashMap<>();
            for (int i = highBit; i >= 0; i--) { // 从最高位开始枚举
                mp.clear();
                mask |= 1 << i;
                int newAns = ans | (1 << i); // 这个比特位可以是 1 吗?
                for (int y : nums) {
                    int maskY = y & mask; // 低于 i 的比特位置为 0
                    if (mp.containsKey(newAns ^ maskY) && mp.get(newAns ^ maskY) * 2 >= y) {
                        ans = newAns; // 这个比特位可以是 1
                        break;
                    }
                    mp.put(maskY, y);
                }
            }
            return ans;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 相关阅读:
    IDEA整合Tomcat服务器、如何创建Web工程、Web工程目录的介绍
    基于element ui 城市选择之间的级联选择
    latex,横线除号
    JAVA毕业设计科技项目在线评审系统计算机源码+lw文档+系统+调试部署+数据库
    关于 ue unreal 虚幻 在编辑器editor未运行情况下 部分材质出现模糊 看不清的问题 的另外一种解决方案猜想
    示例—使用Pytorch堆叠一个神经网络的基础教程
    ContextInfo.get_full_tick 获取最新分笔数据
    数据结构初阶--二叉树介绍(基本性质+堆实现顺序结构)
    LeetCode-15. 三数之和-Java-medium
    批量实现身份证识别(标签-安全|关键词-身份证识别)
  • 原文地址:https://blog.csdn.net/qq_42958831/article/details/134472046