当前位置: 首页 > article >正文

hot100(9)

81.104. 二叉树的最大深度 - 力扣(LeetCode)

后序遍历,从下往上,需要用到下面返回的结果。

public int maxDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        int left = maxDepth(root.left);
        int right = maxDepth(root.right);
        return Math.max(left,right) + 1;
    }

82.102. 二叉树的层序遍历 - 力扣(LeetCode)

层序遍历,队列

List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> levelOrder(TreeNode root) {
        if(root == null) return res;
        level(root);
        return res;
    }
    public void level(TreeNode root){
        Deque<TreeNode> queue = new ArrayDeque<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            int len = queue.size();
            List<Integer> list = new ArrayList<>();
            for(int i = 0 ; i < len ; i++){
                TreeNode node = queue.poll();
                list.add(node.val);
                if(node.left != null){
                    queue.offer(node.left);
                }
                if(node.right != null){
                    queue.offer(node.right);
                }
            }
            res.add(list);
        }
    }

83.101. 对称二叉树 - 力扣(LeetCode)

树形结构,且判断子树是否对称 与 判断原二叉树是否对称 是相同的问题,子问题与原文题具有相同的结构,考虑递归。

public boolean isSymmetric(TreeNode root) {
        return isSymmetricHelper(root.left,root.right);
    }
    public boolean isSymmetricHelper(TreeNode p,TreeNode q){
        if(p == null || q == null){
            return p == q;
        }
        return p.val == q.val && isSymmetricHelper(p.left,q.right) && isSymmetricHelper(p.right,q.left);
    }

84.98. 验证二叉搜索树 - 力扣(LeetCode)

中序遍历下,输出的二叉搜索树节点的数值是有序序列。

有了这个特性,验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。

TreeNode preNode;
    public boolean isValidBST(TreeNode root) {
        if(root == null) return true;
        boolean left = isValidBST(root.left);
        if(preNode != null && preNode.val >= root.val) return false;
        preNode = root;
        boolean right = isValidBST(root.right);
        return left && right;
    }

85.96. 不同的二叉搜索树 - 力扣(LeetCode)

题解:代码随想录_不同的二叉搜索树

1.dp数组及下标含义

dp[i] : 1到i为节点组成的二叉搜索树的个数为dp[i]个

或者i个不同元素的节点组成的二叉搜索树的数量为dp[i]个

2.确定递推公式

dp[i] += dp[以j为头节点左子树节点数量]*dp[以j为头节点右子树节点数量]

j相当于是头节点的元素,从1遍历到i为止

dp[i] += dp[j-1]*dp[i-j]

3.初始化

dp[0] = 1;

从定义上来讲,空节点也是一颗二叉树,也是一科二叉搜索树,可以说得通。

同时为了满足递推公式的乘法,避免结果都为0,dp[0]需要初始化为1

4.遍历顺序

i从大到小,遍历i里每一个数作为头节点的状态,用j来遍历

5.举例推导dp数组

public int numTrees(int n) {
        int[] dp = new int[n+1];
        dp[0] = 1;
        for(int i = 1 ; i <= n; i++){
            for(int j = 1 ; j <= i ; j++){
                dp[i] += (dp[j-1] * dp[i-j]);
            }
        }
        return dp[n];
    }

86.94. 二叉树的中序遍历 - 力扣(LeetCode)

List<Integer> res = new ArrayList<>();
    public List<Integer> inorderTraversal(TreeNode root) {
        inOrder(root);
        return res;
    }
    public void inOrder(TreeNode root){
        if(root == null){
            return;
        }
        inOrder(root.left);
        res.add(root.val);
        inOrder(root.right);
    }

87.85. 最大矩形 - 力扣(LeetCode)

题解:85.最大矩形题解 - 力扣

I暴力优化

class Solution {
    public int maximalRectangle(char[][] matrix) {
        int m = matrix.length;
        if (m == 0) {
            return 0;
        }
        int n = matrix[0].length;
        int[][] left = new int[m][n];

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == '1') {
                    left[i][j] = (j == 0 ? 0 : left[i][j - 1]) + 1;
                }
            }
        }

        int ret = 0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == '0') {
                    continue;
                }
                int width = left[i][j];
                int area = width;
                for (int k = i - 1; k >= 0; k--) {
                    width = Math.min(width, left[k][j]);
                    area = Math.max(area, (i - k + 1) * width);
                }
                ret = Math.max(ret, area);
            }
        }
        return ret;
    }
}

单调栈

public int maximalRectangle(char[][] matrix) {
        int m = matrix.length;
        if(m == 0){
            return 0;
        }
        int n = matrix[0].length;
        int[][] left = new int[m][n];
        for(int i = 0 ; i < m ; i++){
            for(int j = 0 ; j < n ; j++){
                if(matrix[i][j] == '1'){
                    left[i][j] = (j == 0 ? 0 : left[i][j-1]) + 1;
                }
            }
        }
        int res = 0;
        for(int j = 0 ; j < n ; j++){
            int[] up = new int[m];
            int[] down = new int[m];
            Deque<Integer> stack = new ArrayDeque<>();
            for(int i = 0 ; i < m;  i++){
                while(!stack.isEmpty() && left[stack.peek()][j] >= left[i][j]){
                    stack.pop();
                }
                if(stack.isEmpty()){
                    up[i] = -1;
                }else{
                    up[i] = stack.peek();
                }
                stack.push(i);
            }
            stack.clear();
            for(int i = m - 1 ; i >= 0 ; i--){
                while(!stack.isEmpty() && left[stack.peek()][j] >= left[i][j]){
                    stack.pop();
                }
                if(stack.isEmpty()){
                    down[i] = m;
                }else{
                    down[i] = stack.peek();
                }
                stack.push(i);
            }
            for(int i = 0 ; i < m ; i++){
                int height = down[i] - up[i] - 1;
                int area = height * left[i][j];
                res = Math.max(area,res);
            }
        }
        return res;
    }

88.84. 柱状图中最大的矩形 - 力扣(LeetCode)

单调栈

public int largestRectangleArea(int[] heights) {
        int[] left = new int[heights.length];
        int[] right = new int[heights.length];
        int res = 0;
        Deque<Integer> stack = new ArrayDeque<>();
        for(int i = 0 ; i < heights.length ; i++){
            while(!stack.isEmpty() && heights[stack.peek()] >= heights[i]){
                stack.pop();
            }
            left[i] = stack.isEmpty() ? -1 : stack.peek();
            stack.push(i);
        }
        stack.clear();
        for(int i = heights.length - 1 ; i >= 0 ; i--){
            while(!stack.isEmpty() && heights[stack.peek()] >= heights[i]){
                stack.pop();
            }
            right[i] = stack.isEmpty() ? heights.length : stack.peek();
            stack.push(i);
        }
        for(int i = 0 ; i < heights.length ; i++){
            res = Math.max((right[i] - left[i] - 1)*heights[i],res);
        }
        return res;
    }

每个元素至多进出栈一次

时间复杂度O(n) 空间复杂度O(n)

单调栈+常数优化

public int largestRectangleArea(int[] heights) {
        int[] left = new int[heights.length];
        int[] right = new int[heights.length];
        Arrays.fill(left,-1);
        Arrays.fill(right,heights.length);
        int res = 0;
        Deque<Integer> stack = new ArrayDeque<>();
        for(int i = 0 ; i < heights.length ; i++){
            while(!stack.isEmpty() && heights[stack.peek()] >= heights[i]){
                right[stack.peek()] = i;
                stack.pop();
            }
            left[i] = stack.isEmpty() ? -1 : stack.peek();
            stack.push(i);
        }
        
        for(int i = 0 ; i < heights.length ; i++){
            res = Math.max((right[i] - left[i] - 1)*heights[i],res);
        }
        return res;
    }

时间复杂度O(n) 空间复杂度(n)

89.1. 两数之和 - 力扣(LeetCode)

哈希思想,空间换时间

public int[] twoSum(int[] nums, int target) {
        int[] res = new int[2];
        Map<Integer,Integer> map = new HashMap<>();
        for(int i = 0 ; i < nums.length ; i++){
            int match = target - nums[i];
            if(map.containsKey(match)){
                res[0] = map.get(match);
                res[1] = i;
                return res;
            }
            map.put(nums[i],i);
        }
        return res;
    }

90.78. 子集 - 力扣(LeetCode)

回溯问题

List<List<Integer>> res = new ArrayList<>();
    List<Integer> path = new ArrayList<>();
    int[] nums;
    public List<List<Integer>> subsets(int[] nums) {
        this.nums = nums;
        dfs(0);
        return res;
    }
    public void dfs(int index){
        res.add(new ArrayList<>(path));
        if(index == nums.length){
            return ;
        }
        for(int i = index ; i < nums.length ; i++){
            path.add(nums[i]);
            dfs(i+1);
            path.remove(path.size() - 1);
        }
    }


http://www.kler.cn/a/539922.html

相关文章:

  • AMD 8845HS 780M核显部署本地deepseek大模型的性能
  • 每日一题——没有重复项数字的全排列
  • 微信点餐系统小程序ssm+论文源码调试讲解
  • 如何在Android Studio中开发一个简单的Android应用?
  • centos7 curl#6 - Could not resolve host mirrorlist.centos.org; 未知的错误 解决方案
  • 【Pytorch函数】PyTorch随机数生成全解析 | torch.rand()家族函数使用指南
  • JavaScript ES6 新特性全览:变量声明、函数语法、数据结构等多方面解析(面试)
  • Python基础-元组tuple的学习
  • MATLAB语言的网络编程
  • TCP服务器与客户端搭建
  • 深度求索与DeepSeek-R1:探索人工智能的新纪元
  • 表单与交互:HTML表单标签全面解析
  • Java编程语言:构建未来数字世界的基石
  • 前端页面如何兼容不同的分辨率
  • OpenAI 宣布免费开放 ChatGPT 搜索,无需注册
  • 快手ip属地是定位吗?怎么改
  • 使用OBS推流,大华摄像头 srs服务器播放
  • AUTOSAR面试题集锦(1)
  • 02.08 多路文件IO
  • ZooKeeper 的典型应用场景:从概念到实践
  • android selinux 问题
  • 【C++篇】 异常处理
  • Docker安装+镜像+错误解决+win11【小记】
  • k8s部署elasticsearch
  • 深入理解C#结构型设计模式:类适配器与对象适配器
  • C++字符串相关内容