力扣第 302 场周赛
大约 2 分钟
力扣第 302 场周赛
比赛时间 2022-07-17。本场周赛国服共 2271 人 AK。刷新了周赛 AK 人数记录。。
T1. 数组能形成多少数对(3 分)
解题思路
模拟。
时间复杂度:O(n)
。
参考代码
class Solution {
public int[] numberOfPairs(int[] nums) {
// 统计频次
Map<Integer, Integer> cntMap = new HashMap<>();
for (int num : nums) {
cntMap.put(num, cntMap.getOrDefault(num, 0) + 1);
}
int[] answer = new int[2];
for (Map.Entry<Integer, Integer> entry : cntMap.entrySet()) {
int cnt = entry.getValue();
// 形成的数对数目
answer[0] += cnt / 2;
if (cnt % 2 != 0) {
// 剩下的整数数目
answer[1] += 1;
}
}
return answer;
}
}
T2. 数位和相等数对的最大和(4 分)
解题思路
贪心。预处理所有数位和对应的元素,枚举每个数位和找 top2 元素更新最大值。
时间复杂度:O(nlogn)
。
参考代码
class Solution {
public int maximumSum(int[] nums) {
Map<Integer, List<Integer>> cntMap = new HashMap<>();
for (int num : nums) {
int digitsSum = getDigitsSum(num);
cntMap.computeIfAbsent(digitsSum, key -> new ArrayList<>()).add(num);
}
int max = -1;
for (Map.Entry<Integer, List<Integer>> entry : cntMap.entrySet()) {
List<Integer> list = entry.getValue();
int size = list.size();
if (size > 1) {
// 取 top1 top2
Collections.sort(list);
max = Math.max(max, list.get(size - 1) + list.get(size - 2));
}
}
return max;
}
// 数位和
private int getDigitsSum(int num) {
int sum = 0;
while (num > 0) {
sum += num % 10;
num /= 10;
}
return sum;
}
}
T3. 裁剪数字后查询第 K 小的数字(5 分)
解题思路
数据范围不大,直接模拟。
时间复杂度:O((mn + nlogn) * l)
。其中 n 为 nums.length
,m 为 nums[i].length
,l 为 queries.length
。
也可用基数排序。
参考代码
class Solution {
public int[] smallestTrimmedNumbers(String[] nums, int[][] queries) {
int[] res = new int[queries.length];
for (int i = 0; i < queries.length; i++) {
res[i] = calc(nums, queries[i]);
}
return res;
}
private int calc(String[] nums, int[] query) {
int k = query[0];
int trim = query[1];
List<Node> list = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
int len = nums[i].length();
String subStr = nums[i].substring(len - trim);
// idx, num
list.add(new Node(i, subStr));
}
list.sort((o1, o2) -> {
if (o1.num.equals(o2.num)) {
return Integer.compare(o1.idx, o2.idx);
}
return o1.num.compareTo(o2.num);
});
return list.get(k - 1).idx;
}
static class Node {
int idx;
String num;
public Node(int idx, String num) {
this.idx = idx;
this.num = num;
}
}
}
T4. 使数组可以被整除的最少删除次数(6 分)
解题思路
只有 numsDivide
的最大公约数的因数才能整除 numsDivide
中的所有数。
时间复杂度:O(nlogA + nlogn)
。其中 A 是 numsDivide
中的最大元素。
参考代码
class Solution {
public int minOperations(int[] nums, int[] numsDivide) {
int divideGCD = numsDivide[0];
for (int i = 1; i < numsDivide.length; i++) {
divideGCD = getGCD(divideGCD, numsDivide[i]);
}
Arrays.sort(nums);
for (int i = 0; i < nums.length && nums[i] <= divideGCD; i++) {
if (divideGCD % nums[i] == 0) {
return i;
}
}
return -1;
}
private int getGCD(int num1, int num2) {
if (num1 == 0) {
return num2;
}
return getGCD(num2 % num1, num1);
}
}
(全文完)