LeetCode 739, 82, 106

news2024/12/28 21:03:30

文章目录

  • 739. 每日温度
    • 题目链接
    • 标签
    • 思路
    • 代码
  • 82. 删除排序链表中的重复元素 II
    • 题目链接
    • 标签
    • 思路
    • 代码
  • 106. 从中序与后序遍历序列构造二叉树
    • 题目链接
    • 标签
    • 思路
      • 二叉树的三种遍历
      • 值与索引的映射
      • 对于后序遍历的使用
      • 对于中序遍历的使用
    • 代码

739. 每日温度

题目链接

739. 每日温度

标签

栈 数组 单调栈

思路

本题求解的是:对于第 i 天,下一个更高温度出现在几天后。抽象一下,就是 求 每个元素之后的更大元素的索引 与 当前元素索引 之差

可以使用 单调栈 的思想解决,维护一个 从栈顶到栈底 温度 单调递增 的栈,这个栈存储未找到等待天数的天的索引。

遍历温度数组,对于第 i 天的温度 temp,如果 栈中有索引 prevIndex(这个索引取自 栈顶,是整个栈中温度最小的天的索引) 并且 该索引指向的温度比 temp 小,则 第 prevIndex 天的下一个更高温度出现在 i - prevIndex 天之后,它找到了自己的等待天数,可以将其移出栈中。重复这步操作,直到 没有未找到等待天数的天(栈中有索引)prevIndex 天的温度比 temp

可以发现:在栈中,越靠近栈顶,索引指向的温度越低;越靠近栈底,索引指向的温度越高。这就是 单调栈,它能解决 求每个元素之后的更大元素 的问题,稍微变形就变成了本题。

代码

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int len = temperatures.length;
        int[] res = new int[len];
        LinkedList<Integer> stack = new LinkedList<>(); // 存储 未找到等待天数 的天的索引
        for (int i = 0; i < len; i++) {
            int temp = temperatures[i]; // 获取第 i 天的温度
            // 给 未找到等待天数 的每天 赋 等待天数 的值
            // 直到 没有未找到等待天数的天的索引 或 之前有一天温度更高
            while (!stack.isEmpty() && temp > temperatures[stack.peek()]) {
                int prevIndex = stack.pop(); // 取出 未找到等待天数 的天数
                res[prevIndex] = i - prevIndex; // 保存等待天数
            }
            stack.push(i); // 将 i 放到栈中,为它寻找更高温度
        }
        return res;
    }
}

82. 删除排序链表中的重复元素 II

题目链接

82. 删除排序链表中的重复元素 II

标签

链表 双指针

思路

本题是去除链表中重复的所有元素,本质上是 删除节点,删除一个节点就是 让前一个节点指向后一个节点,跳过这个节点。发现这里使用到了 前一个节点,所以使用 哨兵节点 指向链表,避免 对删除第一个节点 进行的特殊处理。

要删除多个重复节点,除了原有的 前一个节点的指针 prev这个节点的指针 curr 之外,还得使用一个指针 afterafter 指向不与 curr 重复的节点,最后得让 prev 指向 after,从而删除 从 prevafter 之间的多个重复节点。

如果没有遇到重复节点,就让 prev 正常向右移动,并更新 curr, after

代码

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        ListNode sentinel = new ListNode(0, head); // 哨兵节点,指向原始链表
        ListNode prev = sentinel; // 指向待检查节点,是它的前一个节点
        ListNode curr; // curr 是待检查节点
        ListNode after; // after 是待检查节点的下一个节点,它最终指向不与 curr 重复的节点

        // 给 curr, after 赋值,并在它两个中有一个为 null 时退出循环
        while ((curr = prev.next) != null && (after = curr.next) != null) {
            if (curr.val != after.val) { // 如果 after 不与 after 重复
                prev = prev.next; // 则让 prev 正常向右移动
                continue;
            }

            // 找到不与 curr 重复的节点,null 也算不与 curr 重复
            while ((after = after.next) != null && after.val == curr.val) {
                continue;
            }
            prev.next = after; // 让 prev 指向这个节点
        }

        return sentinel.next; // 返回哨兵节点指向的链表
    }
}

106. 从中序与后序遍历序列构造二叉树

题目链接

106. 从中序与后序遍历序列构造二叉树

标签

树 数组 哈希表 分治 二叉树

思路

本题和 105. 从前序与中序遍历序列构造二叉树 十分相似,不过本题考查的是 中序遍历后序遍历

二叉树的三种遍历

先讲一讲二叉树的三种 (深度优先搜索) 遍历:

  • 前序遍历:先处理本节点的值,再遍历左子树,最后遍历右子树。
  • 中序遍历:先遍历左子树,再处理本节点的值,最后遍历右子树。
  • 后序遍历:先遍历左子树,再遍历右子树,最后处理本节点的值。

例如对于下图:
二叉树
它的三种遍历结果分别如下:

  • 前序遍历[4, 2, 1, 3, 6, 5, 7]
    可以这样分:[4], [2, 1, 3], [6, 5, 7],分别为:本节点、左子树、右子树。
    左子树有三个节点的原因是:中序遍历的本节点 [4] 前有 3 个元素。
  • 中序遍历[1, 2, 3, 4, 5, 6, 7]
    可以这样分:[1, 2, 3], [4], [5, 6, 7],分别为:左子树、本节点、右子树。
    本节点为 [4] 的原因是:前序遍历的第一个元素是 4 后序遍历的最后一个元素是 4
  • 后序遍历[1, 3, 2, 5, 7, 6, 4]
    可以这样分:[1, 3, 2], [5, 7, 6], [4],分别为:左子树、右子树、本节点。
    左子树有三个节点的原因是:中序遍历的本节点 [4] 前有 3 个元素。

由此可见:只要有中序遍历,再加上前序遍历或后序遍历的其中一种,就可以构建一颗二叉树。

值与索引的映射

在构建二叉树时,获取后序遍历的某一个值作为根节点,然后要根据这个值将中序遍历的结果划分成两部分,为了方便划分,可以使用一个 Map 来存储中序遍历的 值 与 索引 的映射

对于后序遍历的使用

仔细观察后序遍历的结果 [1, 3, 2, 5, 7, 6, 4],可以发现一个很奇妙的东西:从后到前,4 是根节点,6 是右子树的根节点,7, 5 是右子树的两个子节点(也算是两个 null 的根节点),2 是左子树的根节点,3, 1 是左子树的两个子节点(也算是两个 null 的根节点)。

在使用递归的前提下,如果 先构建右子树,再构建左子树,最后返回本次构建的树,就可以把 倒序遍历 postorder 的结果 作为每棵树(或子树)的根节点

对于中序遍历的使用

在区间 [inLeft, inRight] 上构建二叉树时,先通过后序遍历找根节点的值 rootVal,然后通过 Map 寻找这个值在中序遍历中对应的索引 index,接着进行划分:在区间 [index + 1, inRight] 上构建右子树,在区间 [inLeft, index - 1] 上构建左子树。最后将本次在区间 [inLeft, inRight] 上构建的二叉树返回。

代码

class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        // 初始化成员变量
        this.inorder = inorder;
        this.postorder = postorder;
        this.postIndex = postorder.length - 1;
        for (int i = 0; i < inorder.length; i++) { // 构建中序遍历的 值 与 索引 的映射
            this.indcies.put(inorder[i], i);
        }

        return build(0, inorder.length - 1);
    }

    private int postIndex; // postorder 数组的索引,指向正在构建的树的根节点
    private int[] inorder; // 中序遍历数组
    private int[] postorder; // 后序遍历数组
    // 中序遍历的 值 与 索引 的映射,key 为 值,value 为 值在中序遍历数组中的索引
    private Map<Integer, Integer> indcies = new HashMap<>();

    // 在中序遍历数组的 [inLeft, inRight] 区间内,构建树
    private TreeNode build(int inLeft, int inRight) {
        if (inLeft > inRight) { // 如果区间内没有节点
            return null; // 则不需要建立二叉树,退出递归
        }

        int rootVal = postorder[postIndex]; // postIndex 指向 postorder 中当前树的根节点的值
        int index = indcies.get(rootVal); // 获取当前根节点的值在 中序遍历数组 中的索引
        
        TreeNode root = new TreeNode(rootVal); // 新建当前树的根节点
        // 先构建右子树,再构建左子树,最后返回本次构建的二叉树
        postIndex--; // 让 postIndex 指向右子树的根节点
        root.right = build(index + 1, inRight); // 构建完右子树后,postIndex 指向左子树的根节点
        root.left = build(inLeft, index - 1);

        return root;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1940398.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

完整创建一个vite前端项目

目录 1.先创建一个vite项目 2.下载第三方依赖 ① 安装路由vue-router ② 安装vuex全局数据管理 ③ 安装element-plus ④ 安装element-plus图标 ⑤ 安装axios发送请求 ⑥ 完整main.js代码模板 3.开发组件 4.登陆页面开发用例 5. 完整项目代码 废话少说&#xff0c;直接…

【C++】 string类的模拟实现

目录 一、我们先创建三个文件分别为 String.h&#xff08;声明&#xff09;、String.cpp&#xff08;定义&#xff09;、teat.cpp&#xff08;测试&#xff09; 二、成员函数 构造函数与析构函数 &#x1f31f;string() &#x1f31f;string(const char* str) &#x1f…

探索SideLlama:浏览器中的本地大型语言模型

在这个数字化时代&#xff0c;浏览器扩展程序已经成为我们日常网络体验中不可或缺的一部分。它们不仅为我们提供了便利&#xff0c;还为我们的浏览体验增添了更多的功能和乐趣。今天&#xff0c;我要介绍的是一个全新的Chrome浏览器扩展程序——SideLlama&#xff0c;它能够让你…

SOMEIPSRV_ONWIRE_03: 从请求中复制请求ID到响应消息

测试目的&#xff1a; 确保服务器在生成响应消息时将请求ID从请求消息复制到响应消息。 描述 本测试用例旨在验证DUT&#xff08;Device Under Test&#xff0c;被测试设备&#xff09;在处理SOME/IP请求和生成相应响应时&#xff0c;是否将请求消息中的请求ID正确复制到了响…

苹果相册里的视频删除了怎么恢复?只需3招,轻松拿捏

一个不小心手滑把苹果手机相册里的视频删除了怎么办&#xff1f;删除了是不是再也找不回来了&#xff1f;那些美好的回忆是不是也从此消散了&#xff1f;当然不是&#xff01;苹果手机相册里的视频删除了怎么恢复&#xff1f;小编这里有3个秘诀&#xff0c;可以让它重新出现在你…

中智讯与黄淮学院共建“嵌入式边缘计算创客工坊”正式签约

7月13日&#xff0c;中智讯(武汉)科技有限公司与黄淮学院共建“嵌入式边缘计算创客工坊”正式签约。出席签约仪式的有黄淮学院电子信息学院党委书记魏迎军同志、院长高有堂教授、副院长吴忠林教授、党委副书记从卫东同志及全体教职工&#xff0c;中智讯(武汉)科技有限公司技术副…

Jackson详解

文章目录 一、Jackson介绍二、基础序列化和反序列化1、快速入门2、序列化API3、反序列化API4、常用配置 三、常用注解1、JsonProperty2、JsonAlias3、JsonIgnore4、JsonIgnoreProperties5、JsonFormat6、JsonPropertyOrder 四、高级特性1、处理泛型1.1、反序列化List泛型1.2、反…

Nexus3 批量上传 jar 包、pom文件

Nexus3 Maven 私服搭建及各种使用 详见**Maven私服搭建及各种使用汇总2020** Maven 配置 Nexus 私服 在 Maven 项目中配置 Nexus 私服&#xff0c;需要在项目的 pom.xml 或 maven 的 settings.xml 文件中添加 Nexus 仓库的配置。 示例&#xff1a; 以下是一个项目的 pom.xml…

word 设置目录中英文字母大写改为小写

选中目录右击“字体”&#xff0c;设置“小型大写字母”。

【Django+Vue3 线上教育平台项目实战】Celery赋能:优化订单超时处理与自动化定时任务调度

文章目录 前言⭐✨&#x1f4ab;&#x1f525;&#x1f4d6;一、Celery⭐1.基本概念及介绍:✨2.使用步骤&#x1f4ab; 二、订单超时 取消订单&#xff08;Celery&#xff09;&#x1f525;具体实现流程&#x1f4d6; 前言⭐✨&#x1f4ab;&#x1f525;&#x1f4d6; 在构建复…

图解 Hadoop 架构 |Yarn、MapReduce

Hadoop Hadoop 是什么 Hadoop 是由 Apache 基金会所开发&#xff0c;维护的分布式系统基础架构主要解决海量数据的存储和海量数据的分析计算问题广义上来说&#xff0c;Hadoop 通常是指一个更广泛的概念——Hadoop 生态圈&#xff0c;包括 MapReduce&#xff0c;HDFS&#xf…

Python面试宝典第16题:跳跃游戏

题目 给你一个非负整数数组 nums &#xff0c;你最初位于数组的第一个下标 &#xff0c;数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true。否则&#xff0c;返回 false。 示例 1&#xff1a; 输…

Lowpoly Style Alpine Woodlands Environment(高山林地)

v1.1中的新增功能:添加了地形的额外网格。 使用此资产包构建您自己的山地或林地级别和景观!还包括一个demoscene。该包包含许多资产:植物、岩石、山脉、树木、建筑、营地和帐篷、墙壁、粒子效果等等。 性能:所有东西都共享一种材质和一种纹理,因此可以将所有东西分批在一起…

0401-403组合逻辑电路的分析设计竞争冒险

组合逻辑电路的分析设计&竞争冒险 4.组合逻辑电路1.目录2.教学基本要求3.序 关于组合逻辑电路 4.1组合逻辑电路分析与设计一、组合逻辑电路分析二、组合逻辑电路的分析步骤&#xff1a;三、组合逻辑电路的分析举例例1 奇校验电路例2.对输入的二进制求反码例3.一个工厂发电的…

git使用、git与idea结合、gitee、gitlab

本文章基于黑马程序javase模块中的"git"部分 先言:git在集成idea中,不同版本的idea中页面显示不同,操作时更注重基于选项的文字;git基于命令操作参考文档实现即可,idea工具继承使用重点掌握 1.git概述 git是目前世界上最先进的分布式文件版本控制系统 分布式:将…

2024年steam好玩的新游:《哈迪斯2》《雨中冒险: 回归》等

今天已经有不少新游上线&#xff0c;下面为大家整理了2024年好玩的steam游戏&#xff0c;一起来看看。 2024值得一玩的新游 1、《哈迪斯2》 哈迪斯2&#xff08;Hades II&#xff09;是Supergiant Games继其广受好评的作品《哈迪斯》之后开发的一款动作角色扮演游戏。 在《哈…

纯净IP的判断标准及代理深度分析

今天&#xff0c;我们测评团队将带大家深入探讨纯净IP的判断标准&#xff0c;并通过实测数据&#xff0c;对极光静态代理与独享云创这两家服务商进行深度剖析&#xff0c;为你揭秘如何挑选那些真正值得信赖的IP代理服务。 一、纯净IP的判断标准 历史记录检查&#xff1a;一个好…

@Resource注解 和 @Autowired 注解的区别!

Resource注解 和 Autowired 注解的区别! 前言: 实习时候第一次拉取了企业级代码(微服务),发现基本上都是Resource注解,自己之前平时没仔细思考 就是按照自己的习惯用的Autowired,平时开发也是单体架构的系统. 理解: Autowired Autowired是spring提供的一个注解,默认是根据类型…

[RL] 马尔可夫决策过程基础

文章结构 目录 一、马尔可夫过程 马尔可夫性质 二、马尔可夫奖励过程 回报&#xff08;Return&#xff09; 贝尔曼方程&#xff08;Bellman equation&#xff09; 贝尔曼方程解析解 蒙特卡洛方法​ 马尔可夫决策过程​ MDP和马尔可夫过程/马尔可夫奖励过程的区别 马…

循环机制(event loop)之宏任务和微任务

一、前言 js任务分为同步任务和异步任务&#xff0c;异步任务又分为宏任务和微任务&#xff0c;其中异步任务属于耗时的任务。 二、宏任务和微任务有哪些&#xff1f; 宏任务&#xff1a;整体代码script、setTimeout、setInterval、setImmediate&#xff08;Node.js&#xff…