ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

周赛题练习-mid模块

2022-07-10 23:00:57  阅读:125  来源: 互联网

标签:连通 return nums int res mid 周赛题 模块 cnt


1864. 构成交替字符串需要的最小交换次数

解题思路

本题要求给定01组成的字符串,求01交换的最小次数组成010..101..

  1. 由于最终结果不是010..就是101..,因此对字符串的字符进行遍历,比较0开头和1开头最终字符串中的0和1差异数
  2. 对结果进行条件判定:
    • 如果两种的结果都无需交换,直接返回0
    • 如果两种都不等,即没法交换产生01相邻字符串,返回-1
    • 两种都能交换,返回最小;否则返回能交换的一种
class Solution {
    public int minSwaps(String s) {
        int len = s.length();
        int dif00 = 0, dif01 = 0;
        int dif10 = 0, dif11 = 0;
        for (int i = 0; i < len; i++) {
            if (i % 2 == 0) {
                if (s.charAt(i) != '0') {
                    dif00++;
                } else {
                    dif10++;
                }
            } else {
                if (s.charAt(i) != '1') {
                    dif01++;
                } else {
                    dif11++;
                }
            }
        }
        if (dif00 == 0 && dif01 == 0 || dif10 == 0 && dif11 == 0) {
            return 0;
        } 
        if (dif00 != dif01 && dif10 != dif11) {
            return -1;
        }
        if (dif00 == dif01 && dif10 == dif11) {
            return Math.min(dif00, dif10);
        } else if (dif00 == dif01) {
            return dif00;
        } else {
            return dif10;
        }
    }
}

2316. 统计无向图中无法互相到达点对数

解题思路

本题的题意是在一张无向图中,求无法互相到达的不同点对数目,[1,0]和[0,1]重复了只算1个点对。由于一个连通集的点都能互相到达,不同连通集的点都无法互相到达,因此该题是要我们求连通集,再进行计算无法互相到达的点对数目。

解法

  1. 使用DFS遍历全图,用vis[i]标记是否遍历过,依次来遍历每一个连通集,计数连通集数量,返回数量
  2. 计算无法互相到达的方法
    • 用变量curCnt表示为当前累计的连通集的点数量和,cnt表示该次DFS计算出新连通集的点数量,相乘累加到结果res,更新curCnt。即新连通集点数*老的总连通集点数,依次迭代
    • 还可以这样做,依次累加 (n - cnt)*cnt,最后/2。这种计算方法可以理解为:当前连通集点数和剩余的连通集点数都是不互相到达的,因此直接相乘,最后去重则/2
class Solution {
    public long countPairs(int n, int[][] edges) {
        List<Integer>[] list = new ArrayList[n];
        Arrays.setAll(list, e -> new ArrayList<>());
        boolean[] vis = new boolean[n];
        for (int[] edge : edges) {
            int x = edge[0];
            int y = edge[1];
            list[x].add(y);
            list[y].add(x);
        }
        long res = 0;
        long curCnt = 0;
        for (int i = 0; i < n; i++) {
            long cnt = countPairs(i, list, vis);
            res = res + curCnt * cnt; // 也可以 res += (n - cnt) * cnt,结果返回 res / 2
            curCnt += cnt;
        }
        return res;

    }

    private long countPairs(int i, List<Integer>[] list, boolean[] vis) {
        if (vis[i]) {
            return 0;
        }
        vis[i] = true;
        long count = 1;
        for (int j : list[i]) {
            count += countPairs(j, list, vis);
        }
        return count;
    }
}

2317. 操作后的最大异或和

解题思路

选择 任意 非负整数 x 和一个下标 i更新 nums[i]nums[i] AND (nums[i] XOR x)

  1. nums[i]逐位异或任意非负整数,相当于把nums[i]修改为任意非负整数
  2. nums[i]逐位与任意非负整数,nums[i]上的位只能1->0,无法0->1
  3. nums 中所有元素 最大 逐位异或和,如果nums 的某个比特位有奇数个1,那么这个比特位异或和的结果就是1。由2可知,只要保证该比特位有1个1即可
  4. 因此通过逐位或运算求出nums在哪些比特位有1能够的带最大 逐位异或和
class Solution {
    public int maximumXOR(int[] nums) {
        int res = 0;
        for (int num : nums) {
            res = res | num;
        }
        return res;
    }
}

标签:连通,return,nums,int,res,mid,周赛题,模块,cnt
来源: https://www.cnblogs.com/loghorizion/p/16464337.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有