力扣第280场周赛
t1.得到0的操作数
题目描述
思路
简单模拟
根据题意,模拟即可。
Python实现
# 简单模拟
class Solution:
def countOperations(self, num1: int, num2: int) -> int:
ans = 0
while num1 and num2:
if num1 >= num2:
num1 -= num2
else:
num2 -= num1
ans += 1
return ans
Java实现
// 简单模拟
class Solution {
public int countOperations(int num1, int num2) {
int ans = 0;
while (num1 > 0 && num2 > 0) {
if (num1 >= num2) {
num1 -= num2;
} else {
num2 -= num1;
}
ans++;
}
return ans;
}
}
辗转相除法
Python实现
# 辗转相除法
class Solution:
def countOperations(self, num1: int, num2: int) -> int:
ans = 0
while num1:
ans += num2 // num1
num1, num2 = num2 % num1, num1
return ans
Java实现
// 辗转相除法
class Solution {
public int countOperations(int num1, int num2) {
int ans = 0;
while (num1 > 0) {
ans += num2 / num1;
int tmp = num1;
num1 = num2 % num1;
num2 = tmp;
}
return ans;
}
}
t2.使数组变成交替数组的最少操作数
题目描述
思路
模拟
根据题意,找到奇偶坐标的最多元素和次多元素,找到次多元素的目的是防止如[1, 2, 2, 2, 2]出现奇偶坐标最多元素都是2的情况。计算出个数后,用数组总长度减去个数即可。
Python实现
class Solution:
def minimumOperations(self, nums: List[int]) -> int:
even_cnt = Counter(nums[::2])
odd_cnt = Counter(nums[1::2])
even_most = even_cnt.most_common(2)
odd_most = odd_cnt.most_common(2)
even_most.append((None, 0))
odd_most.append((None, 0))
ans = 0
for k1, v1 in even_most:
for k2, v2 in odd_most:
if k1 != k2:
ans = max(ans, v1+v2)
return len(nums) - ans
Java实现
class Solution {
public int minimumOperations(int[] nums) {
int n = nums.length;
Map<Integer, Integer> map1 = new HashMap<>();
Map<Integer, Integer> map2 = new HashMap<>();
for (int i = 0; i < n; i++) {
if (i % 2 == 0) {
map1.put(nums[i], map1.getOrDefault(nums[i], 0) + 1);
} else {
map2.put(nums[i], map2.getOrDefault(nums[i], 0) + 1);
}
}
int[][] p1 = check(map1);
int[][] p2 = check(map2);
if (p1[0][0] != p2[0][0]) {
n -= p1[0][1];
n -= p2[0][1];
} else {
n -= Math.max(p1[0][1] + p2[1][1], p1[1][1] + p2[0][1]);
}
return n;
}
private int[][] check(Map<Integer, Integer> map) {
int[][] ans = new int[2][2];
for (Integer key: map.keySet()) {
int value = map.get(key);
if (value > ans[0][1]) {
ans[1][0] = ans[0][0];
ans[1][1] = ans[0][1];
ans[0][0] = key;
ans[0][1] = value;
} else if (value > ans[1][1]) {
ans[1][0] = key;
ans[1][1] = value;
}
}
return ans;
}
}
t3.拿出最少数目的魔法豆
题目描述
思路
排序+枚举
根据题意,操作后最终状态是除了0外,其他所有豆子都一样的数目,假设这个数目为k,
则各个袋子分别有两种情况:
- 袋子中原来的豆子数目小于k,则要把袋子中的全部豆子拿出,拿出的数目为bean;
- 袋子中原来的豆子数目大于k,则要从袋子中拿出bean-k个豆子。
所以,可以先排序,可以想到k为beans数组中的某一个数字时,拿走的魔法豆会更小,所以当k=beans[i]的时候,下标小于i的所有袋子,全部拿走,下标大于i的袋子,拿到只剩beans[i]个豆子。
Python实现
class Solution:
def minimumRemoval(self, beans: List[int]) -> int:
beans.sort()
ans = total = sum(beans)
n = len(beans)
for i, b in enumerate(beans):
tmp = total - b * (n-i)
if tmp < ans:
ans = tmp
return ans
Java实现
class Solution {
public long minimumRemoval(int[] beans) {
Arrays.sort(beans);
int n = beans.length;
long sum = 0, tmp = 0, ans = 0;
for (int i = 0; i < n; i++) {
sum += beans[i];
}
ans = sum;
for (int i = 0; i < n; i++) {
tmp = sum - 1L * (n-i) * beans[i];
if (tmp < ans) {
ans = tmp;
}
}
return ans;
}
}
t4. 数组的最大与和
题目描述
思路
记忆化递归
枚举盒子的状态即可。
Python实现
class Solution:
def maximumANDSum(self, nums: List[int], numSlots: int) -> int:
@lru_cache(None)
def dfs(idx, state):
if idx == len(nums):
return 0
state_lst, ans = list(state), 0
for i, s in enumerate(state):
if s < 2:
state_lst[i] += 1
ans = max(ans, dfs(idx+1, tuple(state_lst)) + ((i+1) & nums[idx]))
state_lst[i] -= 1
return ans
return dfs(0, tuple([0] * numSlots))