Leetcode刷题 2021.02.22

Leetcode刷题 2021.02.22

  • Leetcode766 托普利茨矩阵
  • Leetcode1765 地图中的最高点
  • Leetcode1769 移动所有球到每个盒子所需的最小操作数

Leetcode766 托普利茨矩阵

给你一个 m x n 的矩阵 matrix 。如果这个矩阵是托普利茨矩阵,返回 true ;否则,返回 false 。

如果矩阵上每一条由左上到右下的对角线上的元素都相同,那么这个矩阵是 托普利茨矩阵 。

回上海了,发现假期都没做什么事。马上就要开学了,接下来就是春招和论文盲审了,要加油啊!

这题比较简单,一开始没仔细想,直接按照题目意思遍历了。后来看了题解想了想就是比较左上角的元素。
话说打周赛的时候往往就是这样,为了追求时间,写的代码往往不是最优解,感觉力扣周赛可以加一个按照时间权值给分的系统。

class Solution {
     
    public boolean isToeplitzMatrix(int[][] matrix) {
     
        int m = matrix.length, n = matrix[0].length;
        for(int i = 1; i < m; i++){
     
            for(int j = 1; j < n; j++){
     
            //比较每个元素和左上角的元素即可
                if (matrix[i][j] != matrix[i - 1][j - 1]){
     
                    return false;
                }
            }
        }
        return true;
    }
}

Leetcode1765 地图中的最高点

给你一个大小为 m x n 的整数矩阵 isWater ,它代表了一个由 陆地 和 水域 单元格组成的地图。

如果 isWater[i][j] == 0 ,格子 (i, j) 是一个 陆地 格子。
如果 isWater[i][j] == 1 ,格子 (i, j) 是一个 水域 格子。
你需要按照如下规则给每个单元格安排高度:

每个格子的高度都必须是非负的。
如果一个格子是是 水域 ,那么它的高度必须为 0 。
任意相邻的格子高度差 至多 为 1 。当两个格子在正东、南、西、北方向上相互紧挨着,就称它们为相邻的格子。(也就是说它们有一条公共边)
找到一种安排高度的方案,使得矩阵中的最高高度值 最大 。

请你返回一个大小为 m x n 的整数矩阵 height ,其中 height[i][j] 是格子 (i, j) 的高度。如果有多种解法,请返回 任意一个 。

这题周赛的时候其实看懂题目以后,就马上有直觉用BFS了。但是用BFS是否是对的不是很确定,所以本来想直接把代码复制过来,后来还是自己写了。结果反应这么快了,还是十分钟才写完这题。不懂那些二十分钟就做完的大神是这么做到的。
这题用BFS直觉是因为开始肯定是要从水的位置周围开始做陆地,那就像是水的涟漪一样一圈一圈往外扩散。

class Solution {
     
	//基本就是BFS模板了,没什么好写的
    int[][] directions = new int[][]{
     {
     -1, 0}, {
     1, 0}, {
     0, -1}, {
     0, 1}};
    public int[][] highestPeak(int[][] isWater) {
     
        int m = isWater.length, n = isWater[0].length;
        boolean[][] isVisited = new boolean[m][n];
        int[][] res = new int[m][n];
        Queue<int[]> queue = new LinkedList<>();
        for(int i = 0; i < m; i++){
     
            for(int j = 0; j < n; j++){
     
                if (isWater[i][j] == 1){
     
                    queue.offer(new int[]{
     i, j});
                    isVisited[i][j] = true;
                }
            }
        }
        while (!queue.isEmpty()){
     
            int[] temp = queue.poll();
            for(int x = 0; x < 4; x++){
     
                int dx = temp[0] + directions[x][0], dy = temp[1] + directions[x][1];
                if (dx >= 0 && dx < m && dy >= 0 && dy < n && !isVisited[dx][dy]){
     
                    res[dx][dy] = res[temp[0]][temp[1]] + 1;
                    isVisited[dx][dy] = true;
                    queue.offer(new int[]{
     dx, dy});
                }
            }
        }
        return res;
    }
}

Leetcode1769 移动所有球到每个盒子所需的最小操作数

有 n 个盒子。给你一个长度为 n 的二进制字符串 boxes ,其中 boxes[i] 的值为 ‘0’ 表示第 i 个盒子是 空 的,而 boxes[i] 的值为 ‘1’ 表示盒子里有 一个 小球。

在一步操作中,你可以将 一个 小球从某个盒子移动到一个与之相邻的盒子中。第 i 个盒子和第 j 个盒子相邻需满足 abs(i - j) == 1 。注意,操作执行后,某些盒子中可能会存在不止一个小球。

返回一个长度为 n 的数组 answer ,其中 answer[i] 是将所有小球移动到第 i 个盒子所需的 最小 操作数。

每个 answer[i] 都需要根据盒子的 初始状态 进行计算。

周赛回上海没参加,回来看了下题目,因为数据量只有2000,所以n^2的话也就是四百万的数据,暴力的话也能过。如果周赛的话肯定就直接暴力了,但是这种题目做多了也有直觉了,用前缀和后缀数组,可以优化成O(n)。

class Solution {
     
    public int[] minOperations(String boxes) {
     
        char[] arr = boxes.toCharArray();
        int n = arr.length, sum = 0;
        int[] res = new int[n];
        int[] left = new int[n];
        int[] right = new int[n];
        //统计左边和右边有几个1
        for(int i = 0; i < n; i++){
     
            left[i] = sum;
            if (arr[i] == '1'){
     
                sum++;
            }
            //求一下第一个位置的答案
            if (arr[i] == '1') res[0] += i;
        }
        sum = 0;
        for(int i = n - 1; i >= 0; i--){
     
            right[i] = sum;
            if (arr[i] == '1'){
     
                sum++;
            }
        }
        //利用前缀和后缀数组更新一下答案
        int l = 0, r = res[0];
        for(int i = 1; i < n; i++){
     
        	//如果该位置是0,就直接更新一下
            if (arr[i] == '0'){
     
                l += left[i];
                r -= right[i];
            //如果是1,右边的要按照前面的更新,具体为什么就是找规律了
            }else{
     
                l += left[i];
                r -= right[i - 1];
            }
            res[i] = l + r;
        }
        return res;
    }
}

你可能感兴趣的:(刷题)