LeetCode 196, 73, 105

目录

  • 196. 删除重复的电子邮箱
    • 题目链接
    • 要求
    • 知识点
    • 思路
    • 代码
  • 73. 矩阵置零
    • 题目链接
    • 标签
    • 简单版
      • 思路
      • 代码
    • 优化版
      • 思路
      • 代码
  • 105. 从前序与中序遍历序列构造二叉树
    • 题目链接
    • 标签
    • 思路
    • 代码

196. 删除重复的电子邮箱

题目链接

196. 删除重复的电子邮箱

  • Person的字段为idemail

要求

编写解决方案 删除 所有重复的电子邮件,只保留一个具有最小 id 的唯一电子邮件。

(对于 SQL 用户,请注意你应该编写一个 DELETE 语句而不是 SELECT 语句。)

(对于 Pandas 用户,请注意你应该直接修改 Person 表。)

运行脚本后,显示的答案是 Person 表。驱动程序将首先编译并运行您的代码片段,然后再显示 Person 表。Person 表的最终顺序 无关紧要

知识点

  1. delete:删除数据。形式上类似于select

思路

保留一个具有最小 id 的唯一电子邮件意味着删除所有 比最小 id 的电子邮件的 id 大 且 与其 email 相同 的电子邮件,所以可以使用多表“查询”,首先得限制两个表的 email 相同,然后删除 id 大的那些数据即可。

代码

delete
    p_big
from
    Person p_big,
    Person p_small
where
    p_big.email = p_small.email
and
    p_big.id > p_small.id

73. 矩阵置零

题目链接

73. 矩阵置零

标签

数组 哈希表 矩阵

简单版

思路

如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。这意味着只需要用两个数组,分别存储这行和这列是否有0,如果这行有0,则将这行元素置零;如果这列有0,则将这列元素置零。

代码

class Solution {
    public void setZeroes(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        boolean[] isRow0 = new boolean[m];
        boolean[] isCol0 = new boolean[n];

        // 检查每一行和每一列是否有为0的数字
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == 0) {
                    isRow0[i] = true;
                    isCol0[j] = true;
                }
            }
        }

        // 置零
        for (int i = 0; i < m; i++) {
            if (isRow0[i]) {
                for (int j = 0; j < n; j++) {
                    matrix[i][j] = 0;
                }
            }
        }
        for (int j = 0; j < n; j++) {
            if (isCol0[j]) {
                for (int i = 0; i < m; i++) {
                    matrix[i][j] = 0;
                }
            }
        }
    }
}

优化版

思路

可以将统计每行每列是否有0的数组放到原矩阵中,这里使用每行的第一个元素(列首)和每列的第一个元素(行首)来统计当前行是否有0和当前列是否有0,如果有0,则列首或行首置为0。然后对“整个”(从第二行到最后一行,从第二列到最后一列的)矩阵进行扫描,如果这行第一个元素或这列第一个元素是0,则将该元素置零。

那么问题就来了,既然在此处修改了第一行和第一列,那么该如何判断原始的第一行和第一列是否需要置零呢?使用两个变量提前对第一行和第一列进行判断即可。在 对“整个”(从第二行到最后一行,从第二列到最后一列的)矩阵进行扫描 完毕后,对第一行和第一列进行操作,如果原先第一行有0,则将第一行置零;如果原先第一列有0,则将第一列置零。

注意:这样做不会破坏原矩阵(或者说不影响结果),因为如果某行(或某列)有0,那么这行(或这列)的所有元素都需要被置零。

代码

class Solution {
    public void setZeroes(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        boolean isFirstRow0 = false, isFirstCol0 = false;

        // 检查第一列是否有为0的数字
        for (int i = 0; i < m; i++) {
            if (matrix[i][0] == 0) {
                isFirstCol0 = true;
                break;
            }
        }
        // 检查第一行是否有为0的数字
        for (int i = 0; i < n; i++) {
            if (matrix[0][i] == 0) {
                isFirstRow0 = true;
                break;
            }
        }
        // 检查 第二行到最后一行 第二列到最后一列 是否有为0的数字
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (matrix[i][j] == 0) { // 如果有重复数字
                    matrix[i][0] = matrix[0][j] = 0; // 则将本矩阵的 行首 和 列首 记为0
                }
            }
        }

        // 将 第二行到最后一行 第二列到最后一列 的元素置零
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (matrix[i][0] == 0 || matrix[0][j] == 0) { // 如果 本行首 或 本列首 被置零
                    matrix[i][j] = 0; // 则将该元素置为0
                }
            }
        }
        // 如果原先矩阵的第一行有0,则将第一行置零
        if (isFirstRow0) {
            for (int j = 0; j < n; j++) {
                matrix[0][j] = 0;
            }
        }
        // 如果原先矩阵的第一列有0,则将第一行置零
        if (isFirstCol0) {
            for (int i = 0; i < m; i++) {
                matrix[i][0] = 0;
            }
        }
    }
}

105. 从前序与中序遍历序列构造二叉树

题目链接

105. 从前序与中序遍历序列构造二叉树

标签

树 数组 哈希表 分治 二叉树

思路

注意:如果遍历的结果中有相同的元素,则无法构造二叉树,所以本题中的遍历结果都是无重复值的。

先来思考一下只有中序遍历应该如何构造二叉树?众所周知,中序遍历是先遍历左子树、再处理本节点、最后遍历右子树,所以说在中序遍历的结果中,中间元素是父节点(前提是它左子树的节点数等于右子树的节点数),中间元素的左子区间为它的左子树,中间元素的右子区间为它的右子树。

根据中间节点把整个遍历结果拆分为两个子区间,这两个子区间也有这样的性质:子区间的中间元素是父节点(前提是它左子树的节点数等于右子树的节点数),中间元素的左子区间为它的左子树,右子区间为它的右子树。

例如底下的二叉树,它的中序遍历结果为[1, 2, 3, 4, 5, 6, 7],第一个父节点(根节点)为4,然后分出[1, 2, 3][5, 6, 7]这两个子区间。在[1, 2, 3]中找到父节点2,在[5, 6, 7]中找到父节点6,接着将区间分为长度为1的子区间。此时直接将这个值作为叶子节点(没有子节点的节点)即可。

二叉树

既然只需要知道中序遍历就能够构造二叉树,那为什么还要前序遍历的结果?这是因为存在一种二叉树,这种二叉树有些节点只有一个子节点,就不能确定哪个节点是父节点。

比如底下的二叉树,它的中序遍历结果为[2, 3, 4, 5, 6, 7],此时就不能轻易地将4作为第一个父节点了,因为4的左右子树的节点数不相等。所以只知道中序遍历的结果是无法构造二叉树的,因为无法确定父节点

在这里插入图片描述

在前序遍历的结果[4, 2, 3, 6, 5, 7]中,第一个元素4就是第一个父节点,然后在中序遍历的结果[2, 3, 4, 5, 6, 7]中寻找父节点,并划分左子树[2, 3]和右子树[5, 6, 7]

发现左子树含有的元素[2, 3] 和 前序遍历结果[4, 2, 3, 6, 5, 7]去掉父节点4后截取前2个元素(2是左子树的长度)的结果[2, 3]含有的元素 恰好相同,右子树含有的元素[5, 6, 7] 和 前序遍历结果[4, 2, 3, 6, 5, 7]去掉父节点4后截取后3个元素(3是右子树的长度)的结果[6, 5, 7]含有的元素 恰好相同。

所以构造二叉树的策略就确定了:将前序遍历区间内第一个值作为二叉树的父节点,在中序遍历的结果中寻找这个值,然后将这个值左边的区间定义为左子树,右边的区间定义为右子树,接着将前序遍历的结果也进行划分,去除第一个元素后,将前n(n是中序遍历划分的左子树的长度)个元素作为左子树,将后m(m是中序遍历划分的右子树的长度)个元素作为右子树。划分完这两个数组后,分别构造左子树和右子树。

代码

class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if (preorder.length == 0) { // 如果preorder的长度为0
            return null; // 则退出递归
        }

        int parentValue = preorder[0]; // 记录父节点的值
        TreeNode parent = new TreeNode(parentValue); // 以preorder的第一个值作为父节点
        for (int i = 0; i < preorder.length; i++) {
            if (inorder[i] == parentValue) { // 如果在inorder中找到父节点
                int[] preLeft = Arrays.copyOfRange(preorder, 1, i + 1); // 截取preorder的左子树区间
                int[] preRight = Arrays.copyOfRange(preorder, i + 1, inorder.length); // 截取preorder的右子树区间

                int[] inLeft = Arrays.copyOfRange(inorder, 0, i); // 截取inorder的左子树区间
                int[] inRight = Arrays.copyOfRange(inorder, i + 1, inorder.length); // 截取inorder的右子树区间

                parent.left = buildTree(preLeft, inLeft); // 构造左子树
                parent.right = buildTree(preRight, inRight); // 构造右子树

                break;
            }
        }
        return parent; // 返回本轮递归的父节点
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

我遭遇的奥数难题(持续更新)

第一题 地上有四堆石子&#xff0c;石子数分别是1、9、15、31。如果每次从其中的三堆同时各取出1个&#xff0c;然后都放入第四堆中&#xff0c;那么&#xff0c;能否经过若干次操作&#xff0c;使得四堆石子的个数都相同?(如果能&#xff0c;请说明具体操作&#xff0c;不能…

【html】许多大型网页都会有一个自己的主题色

许多网站确实会选择一种或几种特定的颜色作为他们的主题色&#xff0c;这通常是为了建立品牌识别度和一致性。 主题色在网站设计中起着至关重要的作用&#xff0c;它们不仅影响网站的视觉效果&#xff0c;还能传达品牌的情感和价值观。选择适当的主题色可以增强用户的品牌记忆…

从传统到智能:工业园区消防管理开始华丽转身

一、工业园区的消防管理现状 然而&#xff0c;当我们审视当前工业园区的消防管理现状时&#xff0c;不难发现其中存在诸多不足。首先&#xff0c;消防信息的智能化程度低&#xff0c;仿佛一位年迈的守望者&#xff0c;力不从心&#xff0c;难以即时将现场的数据信息传达至指挥…

重定向与转发

转发参数不会自动包含在新的请求中。若要将参数传递给重定向地址&#xff0c;可以在服务器端显式地添加参数到重定向URL中。 在重定向URL中包含参数 import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; impor…

TCP的pop网络模式

TCP的pop网络模式 1、tcp连接的状态有以下11种 CLOSED&#xff1a;关闭状态LISTEN&#xff1a;服务端状态&#xff0c;等待客户端发起连接请求SYN_SENT&#xff1a;客户端已发送同步连接请求&#xff0c;等待服务端相应SYN_RECEIVED&#xff1a;服务器收到客户端的SYN请请求&…

巨头们涌入的医疗大模型,何时迎来最好的商业时代?_google医疗大模型 医疗大模型

当下极为火爆的大模型&#xff0c;在医疗赛道同样炙手可热。谷歌刚刚发布了准确率达 91.1%、性能远超 GPT-4 系列的多模态医学大模型 Med-Gemini&#xff0c;国内市场亦很热闹。自 2023 年以来&#xff0c;百度、腾讯、京东等诸多大厂都相继加码医疗大模型领域&#xff0c;与医…

C++:Level3阶段测试

1、黑客小知识&#xff1a; &#xff08;1&#xff09;常用的黑客头文件有____和____。 &#xff08;2&#xff09;创建文件的函数叫做________。 &#xff08;3&#xff09;我更新了____个黑客头文件。 &#xff08;4&#xff09;万能头文件包含的黑客头文件是________。 …

2.4G无线收发芯片 XL2401D,SOP16封装,集成单片机,高性价比

XL2401D 芯片是工作在2.400~2.483GHz世界通用ISM频段&#xff0c;片内集成了九齐 NY8A054E单片机的SOC无线收发芯片。芯片集成射频收发机、频率收生器、晶体振荡器、调制解调器等功能模块&#xff0c;并且支持一对多组网和带ACK的通信模式。发射输出功率、工作频道以及通信数据…

NoSQL 非关系型数据库 Redis 的使用:

redis是基于内存型的NoSQL 非关系型数据库&#xff0c;本内容只针对有基础的小伙伴&#xff0c; 因为楼主不会做更多的解释&#xff0c;而是记录更多的技术接口使用&#xff0c;毕竟楼主不是做教学的&#xff0c;没有教学经验。 关于redis的介绍请自行搜索查阅。 使用redis数据…

【HICE】基于用户认证的虚拟服务搭建

1.创建特定的内容 --账号与密码&#xff08;需要认证访问&#xff09;【里面】 2.编辑配置1.conf的内容&#xff0c;更新httpd 3.编辑hehe网页&#xff08;外部公开&#xff09; cd /www/ echo hehe > hehe/index.html 4.更改本地hosts和window下的解析 5.浏览器下验证内…

新手快速部署Springboot 的Jar包 (图解-BuiId,Maven)

目录 项目的构建 打包前的准备 合理配置pox.xml文件 Build 打包方式 Maven打包方式 Jar包部署 测试后端接口 项目的构建 我的项目是SpringBoot2脚手架 先准备一个相对于的数据库依赖 数据库的任意库 Yaml配置后 才能正常在IDEA中跑起来 打包前的准备 合理配置pox.xm…

【qt】如何获取网卡的IP地址?

网卡相当于是一个翻译官,可以将数据转换成网络信号. 同时也可以将网络信号转换成数据. 我们要用到网卡类QNetmorkInterface 我们获取网卡的所有地址用静态函数allAddresses() 返回的还是一个QhostAddress的容器. QList<QHostAddress> addrList QNetworkInterface::allA…

【笔记】记一次在linux上通过在线安装mysql报错 CentOS 7 的官方镜像已经不再可用的解决方法+mysql配置

报错&#xff08;恨恨恨恨恨恨恨&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff09;&#xff1a; [rootlocalhost ~]# sudo yum install mysql-server 已加载插件&#xff1a;fastestmirror, langpacks Determining fastest mirrors Could not retrie…

达梦数据库系列—22. DPC集群原理

目录 DPC原理 1、系统原理 2、元数据服务 3、数据存储 4、执行计划的生成 5、计算与存储分离 6、动态增删节点 7、分布式事务一致性 第一阶段 预提交 第二阶段 提交 8、RAFT 归档 9、自动故障处理 DPC原理 计划生成节点&#xff08;SP&#xff09;&#xff1a;对外…

【PTGui、Pano2VR6、UE4】VR全景拍摄及漫游交互制作操作实例(更新中)

一、基本思路 首先进行VR全景拍摄&#xff0c;获取高质量的全景图像&#xff1b;然后使用PTGui进行图像拼接&#xff0c;确保图像的连续性与准确性&#xff1b;接着利用Pano2VR6进行VR漫游的制作&#xff0c;添加交互元素与多媒体内容&#xff1b;最后进行作品的调试与优化&am…

Node之Web服务

前言 本文将讲解node的web服务 通过讲解http请求&#xff0c;node创建web服务等知识点让你更加深入的理解web服务和node创建的web服务 HTTP请求是什么&#xff1f; HTTP请求是客户端&#xff08;通常是浏览器或其他应用程序&#xff09;与服务器之间进行通信的一种方式。 …

【Qt之·类QVariant·数据类型】

系列文章目录 文章目录 前言一、概述二、操作及用法1.1 存储数据1.2 获取数据1.3 设置数据1.4 数据类型判断1.5 判断数据是否有效 三、实例演示总结 前言 QVariant是Qt开发中非常重要的一部分&#xff0c;它是Qt的一个核心类&#xff0c;用于处理不同数据类型之间的转换和传递。…

使用vite官网和vue3官网分别都可以创建vue3项目

问: npm init vitelatest 和 npm create vuelatest创建的vue3项目有什么区别? 回答: npm init vitelatest 和 npm create vuelatest 分别是使用 Vite 和 Vue CLI 工具创建 Vue 项目的两种方式&#xff0c;它们之间有几个主要区别&#xff1a; 1. **构建工具&#xff1a;** …

Linux--信号(万字详解!超完整!)

目录 0.预备知识 0.1.基本概念 0.2.信号的捕捉 0.3.理解信号的发送与保存 1.信号的产生&#xff08;阶段一&#xff09; 1.通过kill命令&#xff0c;向指定进程发送指定的信号 2.通过终端按键产生信号&#xff1a;ctrlc&#xff08;信号2&#xff09;&#xff0c;ctrl\(…

南方健康2024米思会:科普患教赋能医药增长闭环,千亿蓝海市场大爆发!

2024年6月25日-28日&#xff0c;在中国•南太湖举办的2024米思会如约而至&#xff0c;顺利落下帷幕&#xff0c;本次大会以“韧进启新局”为主题&#xff0c;以不懈进取的“韧劲”&#xff0c;立身破局&#xff0c;迎变启新。通过4天3夜的思想碰撞和互动交流&#xff0c;引领行…