单周赛 2022.1.9 题解汇总

T1 5976. 检查是否每一行每一列都包含全部整数

对一个大小为 n x n 的矩阵而言,如果其每一行和每一列都包含从 1 到 n 的 全部 整数(含 1 和 n),则认为该矩阵是一个 有效 矩阵。

给你一个大小为 n x n 的整数矩阵 matrix ,请你判断矩阵是否为一个有效矩阵:如果是,返回 true ;否则,返回 false 。

 

 

解题思路:可以使用 set 进行去重,但是 n 的大小最高是100,所以我们可以用数组来代替set进行去重操作,只需遍历每行每列没有重复数字即可,如果有,返回false。没有,返回true。 

代码和提交结果如下:

class Solution {
    public boolean checkValid(int[][] matrix) {
        int len = matrix.length;        
        for(int row = 0 ; row < len ; row++){
            int rowN[] = new int[matrix.length+1];
            int colN[] = new int[matrix.length+1];
            for(int col = 0 ; col < len ; col++){
                if(rowN[matrix[row][col]] > 0){
                    return false;
                }else{
                    rowN[matrix[row][col]]++;
                }
                if(colN[matrix[col][row]] > 0){
                    return false;
                }else{
                    colN[matrix[col][row]]++;
                }     
            }            
        }
        return true;   
    }    
}

 总结:因为用数组代替了 set 耗时从 25ms 下降到了 4ms 。 

T2 5977. 最少交换次数来组合所有的 1 II

交换 定义为选中一个数组中的两个 互不相同 的位置并交换二者的值。

环形 数组是一个数组,可以认为 第一个 元素和 最后一个 元素 相邻 。

给你一个 二进制环形 数组 nums ,返回在 任意位置 将数组中的所有 1 聚集在一起需要的最少交换次数。

 

 

 

 

解题思路:滑动窗口 

① 遍历数组得到数字 1 的个数,数字 1 的个数就是窗口的大小

② 将滑窗在数组中从左到右进行移动,每次滑窗中数字 0 的个数就是需要交换的次数,因为我们只需要将其中的数字 0 ,与滑窗外面的数字 1 交换即可达到题目要求。

③ 滑窗移动到数组末端,移动的过程中不断的更新最小次数即可。

 

*根据题意,数组是循环的,所以在上述方法的基础上,我们可以自己构建一个长度为 原数组长度+ 滑窗大小(数字 1 的个数)的数组,新数组为 原数组 与 原数组前滑窗大小个数的元素组成。

以 示例3 举例:

代码和提交结果如下:

class Solution {
    public int minSwaps(int[] nums) {
        int num1 = 0;
        for(int i = 0; i < nums.length; i++) {
            if(nums[i] == 1) {
                num1++;
            }
        }

        int lNum[] = new int[nums.length + num1];
        for (int i = 0; i < nums.length; i++) {
            lNum[i] = nums[i];
        }
        for(int i = 0 ; i < num1 ; i++){
            lNum[nums.length+i] = nums[i];
        }

        int cnt = 0;
        for(int i = 0; i < num1; i++) {
            if(lNum[i] == 1) {
                cnt++;
            }
        }
        int maxm = cnt;
        for(int i = 1; i <= lNum.length - num1; i++) {
            if(lNum[i-1] == 1) {
                cnt--;
            }
            if(lNum[i+num1-1] == 1) {
                cnt++;
            }
            maxm = Math.max(maxm, cnt);
        }
        return num1 - maxm;   
    }
}

T3 5978. 统计追加字母可以获得的单词数 

给你两个下标从 0 开始的字符串数组 startWords 和 targetWords 。每个字符串都仅由 小写英文字母 组成。

对于 targetWords 中的每个字符串,检查是否能够从 startWords 中选出一个字符串,执行一次 转换操作 ,得到的结果与当前 targetWords 字符串相等。

转换操作 如下面两步所述:

追加 任何 不存在 于当前字符串的任一小写字母到当前字符串的末尾。
例如,如果字符串为 "abc" ,那么字母 'd'、'e' 或 'y' 都可以加到该字符串末尾,但 'a' 就不行。如果追加的是 'd' ,那么结果字符串为 "abcd" 。
重排 新字符串中的字母,可以按 任意 顺序重新排布字母。
例如,"abcd" 可以重排为 "acbd"、"bacd"、"cbda",以此类推。注意,它也可以重排为 "abcd" 自身。
找出 targetWords 中有多少字符串能够由 startWords 中的 任一 字符串执行上述转换操作获得。返回 targetWords 中这类 字符串的数目 。

注意:你仅能验证 targetWords 中的字符串是否可以由 startWords 中的某个字符串经执行操作获得。startWords  中的字符串在这一过程中 不 发生实际变更。

 

 

解题思路:1 状态压缩 (咱不会)2  排序 + hashset判断

2. ① 将 startWords 数组的所有元素排序后存入 hashset。

    ② 遍历 targetWords 数组的,将每一个元素排序,然后滑窗截取,利用set.contains()判断是否存在,存在 count++,然后 break 跳出滑窗循环去判断 targetWords 的下一个元素,同样的方法。最后返回 count 即可。

代码和提交结果如下:

class Solution {
    public int wordCount(String[] startWords, String[] targetWords) {
        HashSet<String> set = new HashSet();
        for(int i = 0 ; i < startWords.length ; i++){
            String startTemp = startWords[i];
            char[] cs = startTemp.toCharArray();
            Arrays.sort(cs);
            set.add(new String(cs));
        }
        int count = 0;
        for(int i = 0 ; i < targetWords.length ; i++){
            String targetTemp = targetWords[i];
            char[] ct = targetTemp.toCharArray();
            Arrays.sort(ct);
            String word = new String(ct);
            for(int j = 0 ; j < word.length() ; j++){
                String temp = word.substring(0,j) + word.substring(j+1,word.length());
                if(set.contains(temp)){
                    count++;
                    break;
                }
            }
        }
        return count;
    }
}

总结: 状态压缩不会,据说压缩完后耗时有显著降低。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值