LeetCode 1164, 125, 94

目录

  • 1164. 指定日期的产品价格
    • 题目链接
    • 要求
    • 知识点
    • 思路+代码
  • 125. 验证回文串
    • 题目链接
    • 标签
    • 简单版
      • 思路
      • 代码
    • 复杂版
      • 思路
      • 代码
  • 94. 二叉树的中序遍历
    • 题目链接
    • 标签
    • 递归
      • 思路
      • 代码
    • 迭代
      • 思路
      • 代码

1164. 指定日期的产品价格

题目链接

1164. 指定日期的产品价格

  • Products的字段为product_idnew_pricechange_date

要求

  • 编写一个解决方案,找出在 2019-08-16 时全部产品的价格,假设所有产品在修改前的价格都是 10 。
  • 任意顺序 返回结果表。

知识点

  1. in:有一次限制多个字段的功能。例如:
where(id, num)
in (selectid,numfromtb_stock
)

此语句将idnum限制到从tb_stock表中查询到的结果,注意 ()中的字段数 与 子表查询到的字段数 必须是相同的。

  1. max():求最大值的函数。
  2. ifnull():共传入两个参数,如果第一个参数是null,则返回第二个参数。例如ifnull(null, 'no')将会返回no
  3. left join:左连接,将 左表的所有数据 和 右表与左表的交集数据 查询出来。
  4. distinct:对字段的相同值进行去重。

思路+代码

找出在 2019-08-16 时全部产品的价格,
所以需要先查出更新的产品的在 2019-08-16 之前的最迟更新日期max_change_date

selectproduct_id,max(change_date) max_change_date
fromProducts
wherechange_date <= '2019-08-16'
group byproduct_id

然后再求出这些产品在最迟更新日期max_change_date更新的价格new_price

selectproduct_id,new_price
fromProducts
where (product_id,change_date
) in (selectproduct_id,max(change_date) max_change_datefromProductswherechange_date <= '2019-08-16'group byproduct_id
)

最后查出所有的产品id,然后将查到new_price的产品的价格返回,将没有查到new_price的产品按价格为10返回。注意,由于要查出所有的产品id,然后再与 查到new_price部分产品id 进行多表查询,所以得使用 外连接,本题使用了 左外连接 left join

selectid_cnt.product_id,ifnull(new_price, 10) price
from (selectdistinct product_idfromProducts) id_cnt
left join (selectproduct_id,new_pricefromProductswhere (product_id,change_date) in (selectproduct_id,max(change_date) max_change_datefromProductswherechange_date <= '2019-08-16'group byproduct_id)) price_cnt
onid_cnt.product_id = price_cnt.product_id

125. 验证回文串

题目链接

125. 验证回文串

标签

双指针 字符串

简单版

思路

本题的思路很明确,先将所有大写字符转换为小写字符,并移除所有非字母数字字符,然后再对剩下的字符串进行是否是回文串的判断。

是否是回文串可以使用双指针的做法,左指针left从字符串头部向尾部遍历,右指针right从字符串尾部向头部遍历,直到 两个指针相遇 或 左指针的值 比 右指针的值 大,如果发现左指针和右指针指向的字符不相同,则返回false;若能退出遍历,则说明这个字符串是一个回文串,返回true

代码

class Solution {public boolean isPalindrome(String s) {s = s.toLowerCase(); // 将所有大写字符转换为小写字符s = removeNonAlphaOrDight(s); // 移除所有非字母数字字符char[] chars = s.toCharArray();int left = 0, right = chars.length - 1;while (left < right) {if (chars[left] != chars[right]) {return false;}left++;right--;}return true;}// 移除字符串s中的所有非字母数字字符private String removeNonAlphaOrDight(String s) {char[] chars = s.toCharArray();StringBuilder builder = new StringBuilder();for (char ch : chars) {if (Character.isLetterOrDigit(ch)) {builder.append(ch);}}return builder.toString();}
}

复杂版

思路

简单版的执行用时比较长,因为对源字符串进行了 转换 和 移除 的操作。如果不想浪费这些时间,就得在 指针 和 判断 这两个点下功夫:当指针指向 非字符数字字符(空格也是非字符数字字符) 时跳过这个字符,并且需要 在判断左右指针指向的字符是否相等前 将字符转化为小写。

代码

class Solution {public boolean isPalindrome(String s) {char[] chars = s.toCharArray();int left = 0, right = chars.length - 1;while (left < right) {if (!Character.isLetterOrDigit(chars[left])) {left++;continue;}if (!Character.isLetterOrDigit(chars[right])) {right--;continue;}char leftChar = Character.toLowerCase(chars[left]);char rightChar = Character.toLowerCase(chars[right]);if (leftChar != rightChar) {return false;}left++;right--;}return true;}
}

94. 二叉树的中序遍历

题目链接

94. 二叉树的中序遍历

标签

栈 树 深度优先搜索 二叉树

递归

思路

中序遍历就是先遍历本节点的左子节点,然后处理本节点的值,最后遍历本节点的右子节点

例如对于下面这个二叉树:
二叉树

中序遍历这个二叉树的结果是[1, 2, 3, 4, 5, 6, 7],过程为:

从节点4开始
往节点2走
往节点1走
往节点1的左子节点走,发现是null
返回到节点1,输出节点1的值
往节点1的右子节点走,发现是null
返回到节点1,返回到节点2,输出节点2的值
往节点3走
往节点3的左子节点走,发现是null
返回到节点3,输出节点3的值
往节点3的右子节点走,发现是null
返回到节点2,返回到节点4,输出节点4的值
往节点6走
往节点5走
往节点5的左子节点走,发现是null
返回到节点5,输出节点5的值
往节点5的右子节点走,发现是null
返回到节点6,输出节点6的值
往节点7走
往节点7的左子节点走,发现是null
返回到节点7,输出节点7的值
往节点7的右子节点走,发现是null
返回节点6,返回节点4,完毕

理解如上的过程后就清晰了,使用递归将此过程模拟一遍就是如下代码:

代码

class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();inorder(root, res);return res;}private void inorder(TreeNode curr, List<Integer> res) {if (curr == null) { // 如果遇到空节点return; // 直接返回}inorder(curr.left, res); // 先遍历左子节点res.add(curr.val); // 再处理本节点的值inorder(curr.right, res); // 最后遍历右子节点}
}

迭代

思路

使用递归能做出来的题,使用迭代也可以,只不过迭代比较难罢了

对二叉树的前序遍历、中序遍历和后序遍历本质上都是深度优先搜索,即遍历时不是一层一层遍历,而是顺着一个方向走到头,然后再回过头来处理这些值。对于这样的遍历,可以使用 将递归转化为迭代:顺着一个方向走时先将这些节点存起来,然后再弹出最近保存的节点进行处理。

递归的思想和迭代的思想是一样的,只不过实现方式不同,迭代时得分类讨论

当遍历的节点curr不为null时,就先将本节点curr加入栈stack中,然后往左子节点curr.left遍历;

否则遍历的节点currnull,此时还得根据 最近一次加入栈的节点peek = stack.peek() 的右子节点的不同进行分类讨论。

只有在没遍历右子节点时才需要对本节点进行操作(这是中序遍历的思想),当它的右子节点peek.right不是最近一次弹出栈的节点pop时,说明此时还没有遍历右子节点,应该操作本节点,然后弹出并记录本节点pop = stack.pop();当它的右子节点peek.rightnull时,也可以将其看作没有遍历右子节点的情况,操作本节点,然后弹出并记录本节点pop = stack.pop();如果不是以上两种情况,则是peek.right是最近一次弹出栈的节点pop的情况,这意味着已经遍历过右子节点了,只需要弹出并记录本节点pop = stack.pop()即可。

分类讨论到处结束,如果还不是很懂,就看看代码吧。

代码

class Solution {public List<Integer> inorderTraversal(TreeNode root) {LinkedList<TreeNode> stack = new LinkedList<>();List<Integer> res = new ArrayList<>();TreeNode curr = root; // 当前节点TreeNode pop = null; // 最近一次弹出栈的节点while (!stack.isEmpty() || curr != null) {if (curr != null) { // 如果这个节点不为nullstack.push(curr); // 将这个节点保存到栈中curr = curr.left; // 让节点往左子节点走} else { // 此时对应某节点的左子节点为null的情况TreeNode peek = stack.peek(); // 查看最近一次加入栈中的节点if (peek.right == null) { // 没有右子节点 也算 右子节点没有遍历res.add(peek.val); // 处理本节点的值pop = stack.pop(); // 将本节点从栈中弹出,并保存它} else if (peek.right != pop) { // 此时还没有遍历右子节点res.add(peek.val); // 处理本节点的值curr = peek.right; // 将本节点从栈中弹出,并保存它} else { // 此时 最近一次弹出栈的节点 是 最近一次加入栈的节点的右子节点,表示已经处理完了右子节点pop = stack.pop(); // 将本节点弹出,并保存它}}}return res;}
}

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

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

相关文章

AI 编译器技术分享会:上海交大/中科院计算所/微软亚研/智源,他们来了!

4 场 Meetup、3 个城市、19 位嘉宾、1k 行业从业者、累计 100w 曝光&#xff0c; 2023 年 AI 编译器社区小小刷新了一下存在感&#xff0c;我们在非常细分的领域里找到了最为垂直的开发者和工程师&#xff0c;从 0 到 1 建立起一个个小据点&#xff0c;搭建交流平台、促成企内合…

MySQL功能测试-之应用工程

MySQL功能测试-之应用工程 前言pom.xmlapplication.yml 文件common.vo 包ResultVO config 包properties 包DruidConfigPropertyDruidMonitorProperty AutoFillMetaObjectHandlerDruidConfigFluxConfigurationMyBatisPlusConfig controller 包ClientControllerDruidControllerWe…

操作系统之如何使用C语言完成SFJ和SRTJ,并完成他的甘特图

目录 前言 SFJ SRTJ 结束语 前言 不知不觉已经写博客一个月了&#xff0c;前段时间因为学业上的一些原因咕咕咕了&#xff0c;今天我又回来了。今天我给大家带来的是C语言代码完成的SFJ和SRTJ&#xff0c;并且带大家描述他的甘特图。如果有对SFJ和SRTJ不了解的小伙伴可以翻…

Flink Sql Redis Connector

经常做开发的小伙伴肯定知道用flink连接redis的时候比较麻烦&#xff0c;更麻烦的是解析redis数据&#xff0c;如果rdis可以普通数据库那样用flink sql连接并且数据可以像表格那样展示出来就会非常方便。 历时多天&#xff0c;我终于把flink sql redis connector写出来了&…

【C语言】手写学生管理系统丨附源码+教程

最近感觉大家好多在忙C语言课设~ 我来贡献一下&#xff0c;如果对你有帮助的话谢谢大家的点赞收藏喔&#xff01; 1. 项目分析 小白的神级项目&#xff0c;99%的程序员&#xff0c;都做过这个项目&#xff01; 掌握这个项目&#xff0c;就基本掌握 C 语言了&#xff01; 跳…

idea http client GET 请求 报503错误

idea 提供的 http client 插件&#xff0c;在 GET 请求时总是 报503 的错误&#xff0c;但请求URL可以在浏览器中正常访问。 GET localhost:8080/student Response file saved. > 2024-06-20T160906.503.html 有一种原因跟本地配置的代理有关&#xff0c;如下图。如果在…

大模型应用场景在哪?探索人工智能的无限可能

随着人工智能技术的飞速发展&#xff0c;大模型在自然语言处理、计算机视觉、推荐系统等领域取得了显著成果。这些大模型&#xff0c;如OpenAI的GPT-3、谷歌的BERT、百度的ERNIE等&#xff0c;不仅在学术界引起了巨大反响&#xff0c;也在产业界得到了广泛应用。本文将以大模型…

sqlcoder实践

背景 Defog llama-3 意义 翻译自然语言到sql&#xff0c;类似脑机接口&#xff0c;大模型重要应用领域 sql是数据库查询标准;关系数据库&#xff0c;工具(datax,sqoop&#xff0c;logstash,hive)&#xff0c;非关系数据库&#xff08;MongoDB&#xff0c;图数据库&#xff…

上新:NFTScan 正式上线 Bitcoin-brc20 浏览器!

近日&#xff0c;NFTScan 团队正式对外发布了 Bitcoin-brc20 浏览器&#xff0c;将为 Bitcoin 生态的 NFT 开发者和用户提供简洁高效的 NFT 数据搜索查询服务。作为比特币生态中最火热的标准之一&#xff0c;brc20 也吸引着广泛的关注。洞悉其巨大潜力&#xff0c;NFTScan 对 b…

协同编辑:只是在线协作这么简单吗?揭秘协同编辑的深层价值

经常很多朋友咨询&#xff0c;无忧企业文档是否支持协同编辑&#xff0c;首先肯定是支持的。但是&#xff0c;我发现很多人对于“协同编辑”的理解可能比较表面&#xff0c;仅仅停留在多人同时编辑一份文档的层面。实际上&#xff0c;协同编辑的功能远不止于此&#xff0c;它更…

两个方法,批量替换PPT中的字体

经常制作ppt的朋友可能会遇到需要批量替换字体的情况&#xff0c;如果我们想要更换ppt中的字体&#xff0c;今天分享PPT批量替换字体的两个方法。 方法一&#xff1a; 找到功能栏中的编辑选项卡&#xff0c;点击替换 – 替换字体&#xff0c;在里面选择我们想要替换的字体就可…

通过MindSpore API实现深度学习模型

快速入门 将相应的包逐一导入到项目中&#xff0c;这是制作项目的第一步。 import mindspore from mindspore import nn from mindspore.dataset import vision, transforms from mindspore.dataset import MnistDataset 处理数据集 先从网上下载对应的数据集文件,MindSpor…

《C++ Primer》导学系列:第 6 章 - 函数

6.1 函数基础 6.1.1 基本概念 函数是C程序的基本组成单元&#xff0c;用于将代码组织成可以复用的模块。函数通过函数名进行调用&#xff0c;并且可以接受参数和返回值。函数的定义包括函数头和函数体&#xff0c;其中函数头描述了函数的接口&#xff0c;函数体包含了具体的实…

最新OPPO 真我手机 一加手机 使用adb命令永久关闭系统更新教程

使用adb命令永久关闭系统更新 一、先了解手机系统二、Android 11 以下使用adb 命令永久关闭系统更新1、adb 官方下载2、小白开启 USB 调试模式教程&#xff08;熟手跳过&#xff09;三、Android 12 以上使用adb 命令永久关闭系统更新什么您还是不会弄&#xff01;赞赏我&#x…

MYSQL 四、mysql进阶 3(存储引擎)

mysql中表使用了不同的存储引擎也就决定了我们底层文件系统中文件的相关物理结构。 为了管理方便&#xff0c;人们把连接管理、语法解析、查询优化这些并不涉及真实数据存储的功能划分为 Mysql Server的功能&#xff0c;把真实存取数据的功能划分为存储引擎的功能&…

systemd的实现原理

systemd是现代Linux系统中的初始化系统和服务器管理器&#xff0c;而systemctl是用于与systemd交互的命令行工具。 systemd是一个守护进程&#xff0c;systemctl是命令行管理工具&#xff1a;systemd是用于管理Linux系统的初始化过程和后台服务的初始化系统&#xff0c;而syst…

Windows10 + fydeOS双系统!简单几步完成

前言 最近发现小伙伴对于fydeOS热情是真的不减&#xff0c;啧啧啧……今天闲来无事&#xff0c;就来讲讲双系统Windows10 fydeOS的安装方法吧&#xff01; Windows10 FydeOS双系统安装过程其实很简单&#xff0c;不过要建议先安装好Windows10系统。 虽然先安装好fydeOS之后…

SpringBootWeb 篇-入门了解 Vue 前端工程的创建与基本使用

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 基于脚手架创建前端工程 1.1 基于 Vue 开发前端项目的环境要求 1.2 前端工程创建的方式 1.2.1 基于命令的方式来创建前端工程 1.2.2 使用图形化来创建前端工程 1.…

如何建立私域流量?私域流量怎么运营,一文读懂

当全网都在讨论私域流量&#xff0c;你是不是也有很多问号呢&#xff1f; 互联网高速发达&#xff0c;消费形式日新月异&#xff0c;跟不上时代就会被时代淘汰&#xff0c;接下来&#xff0c;我们就从3个层面深度讨论下私域流量究竟是什么&#xff1f;为什么要玩转私域流量&am…

【保姆级教程】Linux 基于 Docker 部署 MySQL 和 Nacos 并配置两者连接

一、Linux 部署 Docker 1.1 卸载旧版本&#xff08;如有&#xff09; sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine1.2 安装 yum-utils 包 sudo yum install -y…