• leetcode - 双周赛114


    一,2869.收集元素的最小操作次数

    1. // 解法:哈希表 + 从右往左遍历
    2. class Solution {
    3. public int minOperations(List<Integer> nums, int k) {
    4. Set<Integer> set = new HashSet<>();
    5. for(int i=1; i<=k; i++){
    6. set.add(i);
    7. }
    8. for(int i=nums.size()-1; i>=0; i--){
    9. if(set.contains(nums.get(i))){
    10. set.remove(nums.get(i));
    11. }
    12. if(set.size() == 0)
    13. return nums.size()-i;
    14. }
    15. return -1;
    16. }
    17. }

    二,2870.使数组为空的最小操作次数 

    首先明确一个点:2 和 3 可以组成除了 1 以外的所有的正整数。

    证明:设一个正整数 X ,X > 1

               1)   X % 3 = 0,肯定可以

               2) X % 3 = 1,可以把最后一个3拿出来和剩下的1组成4,而4可以被2整除

               3) X % 3 = 2,剩余的2可以被2整除

    再看题目,我们先统计每个相同元素出现的次数,然后根据上方的结论得出答案。 

    1. class Solution {
    2. public int minOperations(int[] nums) {
    3. Map<Integer,Integer> map = new HashMap<>();
    4. int ans = 0;
    5. for(int x : nums)
    6. map.put(x,map.getOrDefault(x,0)+1);
    7. for(Map.Entry<Integer,Integer> x : map.entrySet()){
    8. int val = x.getValue();
    9. if(val == 1) return -1;
    10. if(val % 3 == 0) ans += val/3;
    11. if(val % 3 == 1) ans += (val-3)/3+2;
    12. if(val % 3 == 2) ans += val/3+1;
    13. }
    14. return ans;
    15. }
    16. }

     三,2871.将数组分割成最多数目的子数组

    我们先来讲一下 & 的性质,0&0=0,0&1=0,1&1=1

    推出:1)当两个数进行按位与操作,得到的数字 >= 两个数字的最小值。

               2)参与&运算的数越多,得到的数就越小。(AND最小值是将数组nums的全部元素进行&操作)

    题目要我们在保证按位与AND值最小的情况下,尽可能多的分割数组,求最多子数组个数。

    假设AND最小值为 a,将数组分成n个子数组时,分割后得到的AND值肯定大于等于 n*a。

    推出:要想分割子数组,即 a >= n*a,我们的 a 即 AND最小值一定要为0,否则不能分割。

    要想得到做多的子数组,遍历数组,进行&运算,一旦遇到 a = 0,ans += 1

    1. class Solution {
    2. public int maxSubarrays(int[] nums) {
    3. int ans = 0;
    4. int a = -1;//-1的补码是全1,-1&n=n
    5. for(int i=0; i<nums.length; i++){
    6. a &= nums[i];
    7. if(a == 0){
    8. a = -1;
    9. ans++;
    10. }
    11. }
    12. return ans==0?1:ans;
    13. }
    14. }

     四,2872.可以被 k 整除连通块的最大数目

    1. class Solution {
    2. int ans = 0;
    3. int[] values;
    4. List<List<Integer>> g = new ArrayList<>();//得到每个点的相邻节点
    5. public int maxKDivisibleComponents(int n, int[][] edges, int[] values, int k) {
    6. this.values = values;
    7. for(int i=0; i<n; i++){
    8. g.add(new ArrayList<Integer>());
    9. }
    10. for(int[] x : edges){
    11. g.get(x[0]).add(x[1]);
    12. g.get(x[1]).add(x[0]);
    13. }
    14. dfs(0,-1,k);
    15. return ans;
    16. }
    17. long dfs(int x, int father, int k){
    18. long s = values[x];
    19. for(int y : g.get(x)){
    20. if(y != father){
    21. s += dfs(y,x,k);
    22. }
    23. }
    24. if(s%k == 0){
    25. s = 0;
    26. ans++;
    27. }
    28. return s;
    29. }
    30. }

  • 相关阅读:
    大模型改变了NLP的游戏规则了吗
    ShardingSphere 集成 CosId 实战
    Jenkins 脚本命令行应用总结
    本地Image Registry Harbor安装
    使用Python制作内马尔的胜利之舞代码版
    Java面试整理(一)
    前端秘法基础式终章----欢迎来到JS的世界
    mina通讯替代socket通讯的使用
    vue 实现弹出菜单,解决鼠标点击其他区域的检测问题
    Docker搭建redis集群
  • 原文地址:https://blog.csdn.net/m0_74859835/article/details/133607257