文章目录
- 周赛371
-
- [[2932. 找出强数对的最大异或值 I](https://leetcode.cn/problems/maximum-strong-pair-xor-i/)](#2932. 找出强数对的最大异或值 I)
- [[2933. 高访问员工](https://leetcode.cn/problems/high-access-employees/)](#2933. 高访问员工)
-
- [哈希 + 分组排序 + 枚举](#哈希 + 分组排序 + 枚举)
- [[2934. 最大化数组末位元素的最少操作次数](https://leetcode.cn/problems/minimum-operations-to-maximize-last-elements-in-arrays/)](#2934. 最大化数组末位元素的最少操作次数)
- [[2935. 找出强数对的最大异或值 II](https://leetcode.cn/problems/maximum-strong-pair-xor-ii/)](#2935. 找出强数对的最大异或值 II)
周赛371
2932. 找出强数对的最大异或值 I
简单
给你一个下标从 0 开始的整数数组 nums
。如果一对整数 x
和 y
满足以下条件,则称其为 强数对 :
|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 。
示例 2:
输入:nums = [10,100]
输出:0
解释:数组 nums 中有 2 个强数对:(10, 10) 和 (100, 100) 。
这些强数对中的最大异或值是 10 XOR 10 = 0 ,数对 (100, 100) 的异或值也是 100 XOR 100 = 0 。
示例 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 <= nums.length <= 50
1 <= nums[i] <= 100
模拟
java
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;
}
}
2933. 高访问员工
中等
给你一个长度为 n
、下标从 0 开始的二维字符串数组 access_times
。对于每个 i
(0 <= 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"] 。
示例 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"] 。
示例 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 <= 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'
组成。
哈希 + 分组排序 + 枚举
java
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;
}
}
2934. 最大化数组末位元素的最少操作次数
中等
给你两个下标从 0 开始的整数数组 nums1
和 nums2
,这两个数组的长度都是 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 。
示例 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 。
示例 3:
输入:nums1 = [1,5,4],nums2 = [2,5,3]
输出:-1
解释:在这个示例中,无法同时满足两个条件。
因此,答案是 -1 。
提示:
1 <= n == nums1.length == nums2.length <= 1000
1 <= nums1[i] <= 109
1 <= nums2[i] <= 109
枚举(脑筋急转弯)
java
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;
}
}
2935. 找出强数对的最大异或值 II
困难
给你一个下标从 0 开始的整数数组 nums
。如果一对整数 x
和 y
满足以下条件,则称其为 强数对 :
|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 。
示例 2:
输入:nums = [10,100]
输出:0
解释:数组 nums 中有 2 个强数对:(10, 10) 和 (100, 100) 。
这些强数对中的最大异或值是 10 XOR 10 = 0 ,数对 (100, 100) 的异或值也是 100 XOR 100 = 0 。
示例 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 <= nums.length <= 5 * 104
1 <= nums[i] <= 220 - 1
哈希表
java
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;
}
}