力扣第280场周赛


t1.得到0的操作数

题目描述

得到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))
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值