「力扣」周赛第 17 场双周赛题解(Java)

这周做出来 3 题。

第 1 题:

竞赛页地址:https://leetcode-cn.com/problems/decompress-run-length-encoded-list/

Java 代码:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Solution {

    public int[] decompressRLElist(int[] nums) {
        int len = nums.length;
        List<Integer> res = new ArrayList<>(len);

        for (int i = 0; i < len / 2; i++) {
            int count = nums[2 * i];
            int val = nums[2 * i + 1];

            for (int j = 0; j < count; j++) {
                res.add(val);
            }
        }
        return res.stream().mapToInt(Integer::intValue).toArray();
    }

    public static void main(String[] args) {
        int[] nums = {1, 2, 3, 4};
        Solution solution = new Solution();
        int[] res = solution.decompressRLElist(nums);
        System.out.println(Arrays.toString(res));
    }
}

第 2 题:

竞赛页地址:https://leetcode-cn.com/problems/matrix-block-sum/

参考「力扣」第 304 题:[“二维区域和检索 - 矩阵不可变”](二维区域和检索 - 矩阵不可变) 的做法。

思路:

  • 先计算前缀和矩阵;
  • 再计算有效区域的左上角以及右下角的坐标;
  • 再使用前缀和矩阵以 O ( 1 ) O(1) O(1) 复杂度计算区域之和。

Java 代码:

import java.util.Arrays;

public class Solution {

    /**
     * 前缀和矩阵
     */
    private int[][] preSum;

    public int[][] matrixBlockSum(int[][] mat, int K) {
        // 行数和列数不用特判,因为题目已经说了不为 0
        int rows = mat.length;
        int cols = mat[0].length;

        // 初始化的时候多设置一行,多设置一列
        preSum = new int[rows + 1][cols + 1];

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                preSum[i + 1][j + 1] = preSum[i + 1][j] + preSum[i][j + 1] - preSum[i][j] + mat[i][j];
            }
        }

        int[][] res = new int[rows][cols];
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                // 左上角横纵坐标
                int row1 = Math.max(i - K, 0);
                int col1 = Math.max(j - K, 0);

                // 右下角横纵坐标
                int row2 = Math.min(i + K, rows - 1);
                int col2 = Math.min(j + K, cols - 1);
                res[i][j] = sumRegion(row1, col1, row2, col2);
            }
        }
        return res;
    }

    public int sumRegion(int row1, int col1, int row2, int col2) {
        return preSum[row2 + 1][col2 + 1]
                - preSum[row1][col2 + 1]
                - preSum[row2 + 1][col1]
                + preSum[row1][col1];
    }
}

复杂度分析

  • 时间复杂度: O ( M N ) O(MN) O(MN),这里 M M M 是矩阵的行数, N N N 是矩阵的列数;
  • 空间复杂度: O ( M N ) O(MN) O(MN)

第 3 题:

竞赛页地址:https://leetcode-cn.com/contest/biweekly-contest-17/problems/sum-of-nodes-with-even-valued-grandparent/

思路:层序遍历。

  • 如果当前结点的值是偶数,给它的孩子结点一个标记(将孩子结点的值修改为负数)。
  • 出队的时候,检测结点的值。如果结点的值是负数,它的孩子节点入队的时候就顺便把值全部加起来。
  • 因为值在修改之前就已经加入了结果,在遍历完成以后不需要把结点值修改回去。

Java 代码:

import java.util.LinkedList;
import java.util.Queue;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}


public class Solution {

    public int sumEvenGrandparent(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        int res = 0;
        while (!queue.isEmpty()) {
            TreeNode top = queue.poll();
            boolean flag = false;
            if ((top.val & 1) == 0) {
                // 表示它的孩子节点开始收集工作
                flag = true;
            }

            if (top.left != null) {
                if (top.val < 0) {
                    res += top.left.val;
                }
                if (flag) {
                    top.left.val *= -1;
                }
                queue.add(top.left);
            }

            if (top.right != null) {
                if (top.val < 0) {
                    res += top.right.val;
                }

                if (flag) {
                    top.right.val *= -1;
                }
                queue.add(top.right);
            }
        }
        return res;
    }
}

你可能感兴趣的:(力扣)