13-周赛347总结

简介: 13-周赛347总结

13-周赛347总结

第三题想太复杂了,贪心想到了真的好简单

第四题思路正确但是代码写不出来,没有想到可以用TreeMap+dp

移除字符串中的尾随零【LC2710】

给你一个用字符串表示的正整数 num ,请你以字符串形式返回不含尾随零的整数 num

  • 思路
    要求不含后置0,因此使用指针指向字符串末尾,移动至字符不为0即可
  • 实现
class Solution {
    public String removeTrailingZeros(String num) {
        int i = num.length() - 1;
        while (num.charAt(i) == '0'){
            i--;
        }
        return num.substring(0, i + 1);
    }
}

image.png

对角线上不同值的数量差【LC2711】

给你一个下标从 0 开始、大小为 m x n 的二维矩阵 grid ,请你求解大小同样为 m x n 的答案矩阵 answer

矩阵 answer 中每个单元格 (r, c) 的值可以按下述方式进行计算:

  • topLeft[r][c] 为矩阵 grid 中单元格 (r, c) 左上角对角线上 不同值 的数量。
  • bottomRight[r][c] 为矩阵 grid 中单元格 (r, c) 右下角对角线上 不同值 的数量。

然后 answer[r][c] = |topLeft[r][c] - bottomRight[r][c]|

返回矩阵 answer

矩阵对角线 是从最顶行或最左列的某个单元格开始,向右下方向走到矩阵末尾的对角线。

如果单元格 (r1, c1) 和单元格 (r, c) 属于同一条对角线且 r1 < r ,则单元格 (r1, c1) 属于单元格 (r, c) 的左上对角线。类似地,可以定义右下对角线。


模拟

  • 思路
    枚举每个单元格,使用两个哈希表分别记录其左上角对角线上和右下角对角线元素的值,哈希表的大小即为不同值的数量,求出两个哈希表大小差值的绝对值即可
  • 实现

class Solution {
    public int[][] differenceOfDistinctValues(int[][] grid) {
        int m = grid.length, n = grid[0].length;
        int[][] res = new int[m][n];
        for (int i = 0; i < m; i++){
            for (int j = 0; j < n; j++){
                Set<Integer> left = new HashSet<>();
                Set<Integer> right = new HashSet<>();
                int x = i - 1, y = j - 1;
                while (x >= 0 && y >= 0){
                    left.add(grid[x][y]);
                    x--;
                    y--;
                }
                x = i + 1;
                y = j + 1;
                while (x < m && y < n){
                    right.add(grid[x][y]);
                    x++;
                    y++;
                }
                res[i][j] = Math.abs(left.size() - right.size());
            }
        }
        return res;
    }
}

image.png

class Solution {
    public int[][] differenceOfDistinctValues(int[][] grid) {
        int m = grid.length, n = grid[0].length;
        int[][] res = new int[m][n];
        // 从第一行和第一列的每个位置出发,枚举每条对角线
        for (int k = 0; k < m + n; k++){
            // i = j + k - n;
            int minJ = Math.max(n - k, 0);
            int maxJ = Math.min(m + n - 1 - k, n - 1);
            Set<Integer> set = new HashSet<>();
            // 左上
            for (int j = minJ; j < maxJ; j++){
                int i = j + k - n;
                set.add(grid[i][j]);
                res[i + 1][j + 1] = set.size();
            }
            set.clear();
            // 右下
            for (int j = maxJ; j > minJ; j--){
                int i = k + j - n;
                set.add(grid[i][j]);
                res[i - 1][j - 1] = Math.abs(res[i - 1][j - 1] - set.size());
            }
        }
        return res;
    }
}
作者:灵茶山艾府
链接:https://leetcode.cn/problems/difference-of-number-of-distinct-values-on-diagonals/solutions/2287367/cong-o503-dao-o502-by-endlesscheng-5wp4/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

image.png

使所有字符相等的最小成本【LC2712】

给你一个下标从 0 开始、长度为 n 的二进制字符串 s ,你可以对其执行两种操作:

  • 选中一个下标 i 并且反转从下标 0 到下标 i(包括下标 0 和下标 i )的所有字符,成本为 i + 1
  • 选中一个下标 i 并且反转从下标 i 到下标 n - 1(包括下标 i 和下标 n - 1 )的所有字符,成本为 n - i

返回使字符串内所有字符 相等 需要的 最小成本

反转 字符意味着:如果原来的值是 ‘0’ ,则反转后值变为 ‘1’ ,反之亦然。

image.png

  • 反转下标 0 到下标 i-1的所有字符,成本为 i ->反转后对后续字符没有影响
  • 反转下标 i 到下标 n-1的所有字符,成本为 n-i ->反转后后续字符全部进行了反转,与之前的字符串是等价的,对最终成本没有影响
  • 实现
class Solution {
    public long minimumCost(String s) {
        long res = 0L;
        int n = s.length();
        for (int i = 1; i < n; i++){
            if (s.charAt(i) != s.charAt(i - 1)){
                res += Math.min(i, n - i);
            }
        }
        return res;
    }
}
作者:灵茶山艾府
链接:https://leetcode.cn/problems/minimum-cost-to-make-all-characters-equal/solutions/2286922/yi-ci-bian-li-jian-ji-xie-fa-pythonjavac-aut0/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

image.png

矩阵中严格递增的单元格数【LC2713】

给你一个下标从 1 开始、大小为 m x n 的整数矩阵 mat,你可以选择任一单元格作为 起始单元格

从起始单元格出发,你可以移动到 同一行或同一列 中的任何其他单元格,但前提是目标单元格的值 严格大于 当前单元格的值。

你可以多次重复这一过程,从一个单元格移动到另一个单元格,直到无法再进行任何移动。

请你找出从某个单元开始访问矩阵所能访问的 单元格的最大数量

返回一个表示可访问单元格最大数量的整数。

思路

  • 贪心:由于对于每一个位置,你可以移动到 同一行或同一列 中的比它大的其他单元格。为了访问更多的单元格,我们每次应该按增量的最小值方向移动,即从小到大移动。
  • 我们需要记录每个值对应的所有坐标,然后按照值从小到大的顺序访问时每个位置,因此可以使用TreeMap记录,key为值,value为所有位置,类型为List<int[]>

image.png

class Solution {
    public int maxIncreasingCells(int[][] mat) {
        var g = new TreeMap<Integer, List<int[]>>();
        int m = mat.length, n = mat[0].length;
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                // 相同元素放在同一组,统计位置
                g.computeIfAbsent(mat[i][j], k -> new ArrayList<>()).add(new int[]{i, j});
        int ans = 0;
        int[] rowMax = new int[m], colMax = new int[n];
        for (var pos : g.values()) {
            var mx = new int[pos.size()];  // 先把最大值算出来,再更新 rowMax 和 colMax
            for (int i = 0; i < pos.size(); i++) {
                mx[i] = Math.max(rowMax[pos.get(i)[0]], colMax[pos.get(i)[1]]) + 1;
                ans = Math.max(ans, mx[i]);
            }
            for (int k = 0; k < pos.size(); k++) {
                int i = pos.get(k)[0], j = pos.get(k)[1];
                rowMax[i] = Math.max(rowMax[i], mx[k]); // 更新第 i 行的最大 f 值
                colMax[j] = Math.max(colMax[j], mx[k]); // 更新第 j 列的最大 f 值
            }
        }
        return ans;
    }
}
作者:灵茶山艾府
链接:https://leetcode.cn/problems/maximum-strictly-increasing-cells-in-a-matrix/solutions/2286920/dong-tai-gui-hua-you-hua-pythonjavacgo-b-axv0/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

image.png


目录
相关文章
|
7月前
【周赛总结】周赛354
【周赛总结】周赛354
51 0
|
7月前
|
人工智能 BI
12-周赛338总结
12-周赛338总结
56 0
|
7月前
14-周赛348总结
14-周赛348总结
56 0
|
7月前
|
存储
10-周赛336总结
10-周赛336总结
65 0
|
7月前
9-周赛335总结
9-周赛335总结
56 0
|
算法
LeetCode 周赛(2023/07/08)渐入佳境
- 往期回顾:[LeetCode 单周赛第 351 场 · 一场关于子数组的专题周赛](https://mp.weixin.qq.com/s/0KIaUMEpLZw6poHs3cc7MA)
123 0
|
7月前
【周赛总结】周赛356
【周赛总结】周赛356
63 0
|
7月前
【周赛总结】18-周赛353
【周赛总结】18-周赛353
66 0
|
7月前
|
算法 Windows
【周赛总结】周赛360
【周赛总结】周赛360
51 0
|
7月前
|
算法
8-周赛334总结
8-周赛334总结
56 0