力扣373场周赛题解

第一题:

这个题是一个简单题,数据范围也特别小,所以直接使用模拟方式暴力解答。

直接进行行移动的过程,然后检查移动后的结果是否与移动前相同。

代码:      

​
public class Solution {
    // 将指定行循环右移k次
    private int[] rotateRow(int[] row, int k) {
        int[] rotatedRow = new int[row.length];
        for (int i = 0; i < row.length; i++) {
            rotatedRow[(i + k) % row.length] = row[i];
        }
        return rotatedRow;
    }

    private int[][] rotateMatrix(int[][] matrix, int k) {
        int[][] rotatedMatrix = new int[matrix.length][matrix[0].length];
        for (int i = 0; i < rotatedMatrix.length; i++) {
           if (i % 2 == 0) {
              rotatedMatrix[i] = rotateRow(matrix[i], k % matrix[i].length);
             } else {
                rotatedMatrix[i] = rotateRow(matrix[i], matrix[i].length - (k % matrix[i].length));
             }
         }
        return rotatedMatrix;
    }


    // 检查两个矩阵是否完全相同
    private boolean isSameMatrix(int[][] matrix1, int[][] matrix2) {
        for (int i = 0; i < matrix1.length; i++) {
            for (int j = 0; j < matrix1[0].length; j++) {
                if (matrix1[i][j] != matrix2[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }

    // 判断初始矩阵和最终矩阵是否相同
    public boolean areSimilar(int[][] matrix, int k) {
        int[][] originalMatrix = new int[matrix.length][matrix[0].length];
        for (int i = 0; i < matrix.length; i++) {
            originalMatrix[i] = matrix[i].clone(); // 创建矩阵的副本
        }
        int[][] rotatedMatrix = rotateMatrix(matrix, k); // 循环移动k次
        return isSameMatrix(originalMatrix, rotatedMatrix);
    }
}

​
第二题:

这个题目的思路也比较简单,主要就是两个方面进行考虑,一进行子字符串的截取,二判断子字符串是否是美丽字符串。子字符串的截取采用双指针进行解决,通过双指针的移动来不断截取子字符串然后,去判断当前截取的子字符串两种字符的数量是否满足规则。代码如下:

class Solution {
    public int beautifulSubstrings(String s, int k) {
        int count = 0;
        for (int i = 0; i < s.length(); i++) {
            int vowels = 0;
            int consonants = 0;
            for (int j = i; j < s.length(); j++) {
                char c = s.charAt(j);
                if (isVowel(c)) {
                    vowels++;
                } else {
                    consonants++;
                }
                if (vowels == consonants && (vowels * consonants) % k == 0) {
                    count++;
                }
            }
        }
        return count;
    }
    
    private boolean isVowel(char c) {
        c = Character.toLowerCase(c);
        return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
    }
}
第三题:

这个题目的思路是分组排序,把差距在limit的数字分为一组,每一组中的数据可以直接排序,然后把这个结果插入回原来的数组中,就得到结果。对于这个题目的解决思路就是先把所有元素进行排序然后记录原始的下标,然后通过limit来进行元素的分组。分好组后,针对每个分组的下标进行排序然后把最小的元素放在最小的下标。这样就得到了问题结果。

class Solution {
    public int[] lexicographicallySmallestArray(int[] nums, int limit) {
        int n = nums.length;
        // 将所有元素按照大小排序,并记录原始下标
        List<Pair<Integer, Integer>> list = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            list.add(new Pair<>(nums[i], i));
        }
        list.sort((a, b) -> a.getKey() - b.getKey());

        // 将所有元素划分成若干子段,子段内相邻元素之差不超过 limit
        List<List<Pair<Integer, Integer>>> segments = new ArrayList<>();
        int last = -limit;
        for (int i = 0; i < n; i++) {
            if (list.get(i).getKey() - last > limit) {
                segments.add(new ArrayList<>());
            }
            segments.get(segments.size() - 1).add(list.get(i));
            last = list.get(i).getKey();
        }

        int[] ans = new int[n];
        // 对每个子段分别进行从小到大排序,并填回到序列中
        for (List<Pair<Integer, Integer>> segment : segments) {
            List<Integer> pos = new ArrayList<>();
            for (Pair<Integer, Integer> p : segment) {
                pos.add(p.getValue());
            }
            pos.sort(Comparator.naturalOrder());
            for (int i = 0; i < segment.size(); i++) {
                ans[pos.get(i)] = segment.get(i).getKey();
            }
        }
        return ans;
    }
}

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值