【恒生电子专场】力扣第 244 场周赛(1950 / 4429)

简介: 【恒生电子专场】力扣第 244 场周赛(1950 / 4429)

第一题

题目链接

5776. 判断矩阵经轮转后是否一致

题目简介

给你两个大小为 n x n 的二进制矩阵 mat 和 target 。现 以 90 度顺时针轮转 矩阵 mat 中的元素 若干次 ,如果能够使 mat 与 target 一致,返回 true ;否则,返回 false 。

题目解析

  • 模拟题目,对 mat 数组进行 90度 旋转,来是否能和 target 一样

题目代码

class Solution {
    public boolean findRotation(int[][] mat, int[][] target) {
        for(int i = 0; i < 4; i++){
            if(isSame(mat, target)){
                return true;
            }
            xuan(mat);
        }
        return false;
    }
    public void xuan(int[][] mat){
        int n = mat.length;
        for (int i = 0; i < n / 2; ++i) {
            for (int j = 0; j < (n + 1) / 2; ++j) {
                int temp = mat[i][j];
                mat[i][j] = mat[n-1-j][i];
                mat[n-1-j][i] = mat[n-1-i][n-1-j];
                mat[n-1-i][n-1-j] = mat[j][n-1-i];
                mat[j][n-1-i] = temp;
            }
        }
    }
    public boolean isSame(int[][] mat, int[][] target){
        for(int i = 0; i < mat.length; i++){
            for(int j = 0; j < mat[0].length; j++){
                if(mat[i][j] != target[i][j]){
                    return false;
                }
            }
        }
        return true;
    }
}

第二题

题目链接

5777. 使数组元素相等的减少操作次数

题目简介

给你一个整数数组 nums ,你的目标是令 nums 中的所有元素相等。完成一次减少操作需要遵照下面的几个步骤:

  • 找出 nums 中的 最大 值。记这个值为 largest 并取其下标 i (下标从 0 开始计数)。如果有多个元素都是最大值,则取最小的 i 。
  • 找出 nums 中的 下一个最大 值,这个值 严格小于 largest ,记为 nextLargest 。
  • 将 nums[i] 减少到 nextLargest 。

返回使 nums 中的所有元素相等的操作次数。


20210606140537352.png

题目解析

  • 刚开始以为是个模拟题,模拟了一下,发现出现超时错误
  • 后来发现规律:如数组nums[1,2,3,4,3,2]
  • 将所有的4变成3,需要1次操作
  • 将所有的3变成2,需要3次操作
  • 再将所有的2变成1,需要5次操作
  • 总共需要:1 + 3 + 5 = 8 次操作
  • 所以,我们能找到一个规律:从最大值开始,依次进行减少,所以我们只需要枚举 最大~最小 出现的次数,加起来就可以了

题目代码

class Solution {
    public int reductionOperations(int[] nums) {
        int[] num = new int[100000];
        int min = 100000;
        int max = 0;
        for(int i = 0; i < nums.length; i++){
            num[nums[i]]++;
            min = Math.min(min, nums[i]);
            max = Math.max(max, nums[i]);
        }
        int sum = 0;
        int cnt = 0;
        for(int i = max; i > min; i--){
            if(num[i] != 0){
                cnt += num[i];
                sum += cnt;
            }
        }
        return sum;
    }
}

第三题

题目链接

5778. 使二进制字符串字符交替的最少反转次数

题目简介

给你一个二进制字符串 s 。你可以按任意顺序执行以下两种操作任意次:

  • 类型 1 :删除 字符串 s 的第一个字符并将它 添加 到字符串结尾。
  • 类型 2 :选择 字符串 s 中任意一个字符并将该字符 反转 ,也就是如果值为 ‘0’ ,则反转得到 ‘1’ ,反之亦然。
  • 请你返回使 s 变成 交替 字符串的前提下, 类型 2 的 最少 操作次数 。

我们称一个字符串是 交替 的,需要满足任意相邻字符都不同。

  • 比方说,字符串 “010” 和 “1010” 都是交替的,但是字符串 “0100” 不是。

题目解析

  • 这个题目,一开始我使用的N^2的方法做的,发现超时,后来也没想到优化的办法
  • 对于我们字符串来说,我们最后肯定要变成下方的样子
  • 如果是偶数:
  • 第一种情况:01010101
  • 第二种情况:10101010
  • 如果是奇数:
  • 第一种情况:1010101
  • 第二种情况:0101010
  • 第三种情况:0100101
  • 第四种情况:1011010
  • 这四种情况我们使用滑动窗口来解决:
  • 最原始的N^2的做法:每次进行删除后,重新计算当前字符串与目标串的不同位  
  • 置,最后返回一个min  
  • 优化思路:我们想想,对于 当前字符串与目标串的不同位置 可不可以通过 O(1) 的时间得到?我们可以想到,原字符串不断的进行删除放置末尾,也就相当于使用滑动窗口对于 s+s 进行遍历,如下图所示:

  • 每次滑动窗口的大小都为:s.length()
  • 每次滑动的距离为:1
  • 在滑动的过程中,需要判断当前的值和目标值是否相等,若不等,则增加
  • i >= len,证明进入删除放置末尾的操作了,滑动的时候需要判断丢弃的元素是不是不等的
  • 最后返回即可

题目代码

class Solution {
    public int minFlips(String str) {
        // 字符串的模式
        // 01010101
        // 10101010
        int len = str.length();
        String s = str + str;
        StringBuffer sb1 = new StringBuffer();
        StringBuffer sb2 = new StringBuffer();
        for(int i = 0; i < len; i++){
            sb1.append("01");
            sb2.append("10");
        }
        int num1 = 0;
        int num2 = 0;
        int ans = 10000000;
        for(int i = 0; i < len * 2; i++){
            if(s.charAt(i) != sb1.charAt(i)){
                num1++;
            }
            if(s.charAt(i) != sb2.charAt(i)){
                num2++;
            }
            if(i >= len){
                if(s.charAt(i - len) != sb1.charAt(i-len)){
                    num1--;
                }
                if(s.charAt(i - len) != sb2.charAt(i-len)){
                    num2--;
                }
                ans = Math.min(ans, Math.min(num1, num2));
            }
        }
        return ans;
    }
}
相关文章
|
6月前
|
Go
golang力扣leetcode 第 291 场周赛
golang力扣leetcode 第 291 场周赛
62 0
|
6月前
|
Go vr&ar
golang力扣leetcode 第 288 场周赛
golang力扣leetcode 第 288 场周赛
54 0
|
6月前
|
Go
golang力扣leetcode 第 286 场周赛
golang力扣leetcode 第 286 场周赛
59 0
|
算法 Android开发
LeetCode 周赛上分之旅 #48 一道简单的树上动态规划问题
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
65 1
|
6月前
|
Go
golang力扣leetcode第 294 场周赛
golang力扣leetcode第 294 场周赛
55 0
|
6月前
|
算法 Java Go
golang力扣leetcode 第 293 场周赛
golang力扣leetcode 第 293 场周赛
82 0
|
6月前
|
Go
golang力扣leetcode 第 290 场周赛
golang力扣leetcode 第 290 场周赛
52 0
|
6月前
|
Go C++
golang力扣leetcode 第 284 场周赛
golang力扣leetcode 第 284 场周赛
59 0
|
6月前
|
Go
golang力扣leetcode 第 292 场周赛
golang力扣leetcode 第 292 场周赛
67 0
|
6月前
|
存储
Leetcode第383场周赛
在LeetCode第383场周赛中,选手完成了3道题目。第一题是关于边界上的蚂蚁,蚂蚁根据非零整数数组nums的值移动,返回蚂蚁返回边界上的次数。解题方法是计算数组累加和为0的次数。第二题涉及计算网格的区域平均强度,给定一个灰度图像和阈值,返回每个像素所属区域的平均强度。解题关键在于理解相邻像素和区域定义,并计算平均强度。第三题是恢复单词初始状态的最短时间问题,通过移除前k个字符并添加k个字符,求恢复原词所需的最短时间。解题策略是检查去除前k个字符后的子串是否能作为原词的前缀。
34 1
Leetcode第383场周赛