LeetCode 1351, 1, 208

目录

  • 1351. 统计有序矩阵中的负数
    • 题目链接
    • 标签
    • 简答二分查找
      • 思路
      • 代码
    • 优化
      • 思路
      • 代码
  • 1. 两数之和
    • 题目链接
    • 标签
    • 思路
    • 代码
  • 208. 实现 Trie (前缀树)
    • 题目链接
    • 标签
    • 思路
    • 代码

1351. 统计有序矩阵中的负数

题目链接

1351. 统计有序矩阵中的负数

标签

数组 二分查找 矩阵

简答二分查找

思路

由于矩阵每行都是按 降序 排列的,所以可以针对每行都使用二分查找来查找最后一个不是负数的元素的索引,然后给 总数 加上 本行元素个数 减去 这个索引 再 减一,不过要注意的一点是,最后一个不是负数的元素可能是重复的,所以不能在找到最后一个不是负数的元素后就退出查找,而应该继续到 右子区间 查找,直到找到 最右边的 不是最后一个负数的元素。

代码

class Solution {public int countNegatives(int[][] grid) {int m = grid[0].length; // m是矩阵的列数int left, right;int cnt = 0; // 统计负数的个数for (int[] row : grid) { // 针对矩阵的每行进行操作// 每次都把查找区间限制在 [0, m - 1] 之间left = 0;right = m - 1;while (left <= right) {int mid = left + (right - left >> 1);if (0 > row[mid]) { // 如果 row[mid] < 0right = mid - 1; // 则到左子区间查询(降序数组)} else if (0 < row[mid]) { // 如果 row[mid] > 0left = mid + 1; // 则到右子区间查询(降序数组)} else { // 如果 row[mid] == 0left = mid + 1; // 则到右子区间查询(降序数组)}}cnt += m - right - 1; // 统计本行的负数个数}return cnt;}
}

优化

思路

像上面的多个二分查找之间没有任何联系,每次都是在 [ 0 , m − 1 ] [0, m - 1] [0,m1] 这个大区间进行查询,这样就浪费了这个矩阵的另一个特性:每列也是按降序排列的

那么该如何利用这个特性呢?很简单,有这个特性再加上每行都是降序排列的,就意味着 在上一行中最后一个0出现的位置 一定比 本行中最后一个0出现的位置 要更靠右或相同,所以二分查找本行时不需要将右端点重置为 m - 1,继承上一次的右端点即可。

代码

class Solution {public int countNegatives(int[][] grid) {int m = grid[0].length;int left, right = m - 1;int cnt = 0;for (int[] row : grid) {left = 0;while (left <= right) {int mid = left + (right - left >> 1);if (0 > row[mid]) {right = mid - 1;} else if (0 < row[mid]) {left = mid + 1;} else {left = mid + 1;}}cnt += m - right - 1;}return cnt;}
}

1. 两数之和

题目链接

1. 两数之和

标签

数组 哈希表

思路

本题需要返回元素对应的索引,而不是只返回真假值,所以可以使用 Map 来存储元素的值和索引的键值对,key为元素的值,value为元素的索引。每遍历到一个元素就在 Map 中查找是否有 目标元素 减去 当前元素 的元素,如果有,则返回当前元素和这个元素的索引组成的数组;否则就把当前元素的值和索引存储到 Map 中,遍历下一个元素。

代码

class Solution {public int[] twoSum(int[] nums, int target) {Map<Integer, Integer> map = new HashMap<>();for (int i = 0; i < nums.length; i++) {int curr = nums[i]; // 当前遍历到的元素int need = target - curr; // 需要的元素,满足 当前元素 + 需要元素 = 目标元素if (map.containsKey(need)) {return new int[]{i, map.get(need)};}map.put(curr, i);}return null;}
}

208. 实现 Trie (前缀树)

题目链接

208. 实现 Trie (前缀树)

标签

设计 字典树 哈希表 字符串

思路

本题和 二叉树 有些类似,不过本题是以 小写字符 作为区分子节点的标识,故应该叫 二十六叉树,每个节点都有26个指针,分别指向从 'a''z' 的所有字符的节点。

可以把字符串想像成一串字符序列,而这个字符序列就是二十六叉树的 一条路径,比如对于字符串word = "apple",它的路径就是a -> p -> p -> l -> e,按照路径把这个字符串添加到各层节点上。这就是添加方法 void insert(String word)

在查找时,可以查找这个字符串的字符序列对应的路径是否存在与这个二十六叉树中,即按照这个路径遍历,如果有一个节点不存在,则这个字符串不存在;否则就代表字符串一定存在吗?不一定,例如只添加了一个字符串"apple",而现在要查询"app"是否存在。

那么就不能只保存路径,应该还要保存字符串的结尾字符,也就是保存这个字符是否是字符串的结尾,这样在查找时,就可以通过是否是字符串的结尾来判断这个单词是否存在了。这就是查询方法boolean search(String word)

此外,还要实现boolean startsWith(String prefix)方法。这个方法就是 没添加是否是字符串的结尾的标记前 的查找方法,只要存在这条路径就满足条件,返回true;否则就返回false

代码

class Trie {private static class Node {private static final int SIZE = 26; // 字符数Node[] nexts = new Node[SIZE]; // 存储下一字母的指针数组boolean isEnd; // 记录本节点是否是单词的结尾}private Node root; // 前缀树的根节点public Trie() {root = new Node();}public void insert(String word) {char[] str = word.toCharArray();Node curr = root;for (char c : str){int idx = c - 'a'; // 获取在指针数组中的索引if (curr.nexts[idx] == null) { // 如果这个位置没有字符节点curr.nexts[idx] = new Node(); // 则新建一个字符节点}curr = curr.nexts[idx]; // 往下一个字符节点移动}curr.isEnd = true; // 保存该字符是字符串的最后一个字符}public boolean search(String word) {char[] str = word.toCharArray();Node curr = root;for (char c : str) {int idx = c - 'a'; // 获取在指针数组中的索引if (curr.nexts[idx] == null) { // 如果这个位置没有字符节点return false; // 则说明字符串不存在该树中,返回false}curr = curr.nexts[idx]; // 往下一个字符节点移动}return curr.isEnd; // 返回这个字符是否是字符串的结尾}public boolean startsWith(String prefix) {char[] str = prefix.toCharArray();Node curr = root;for (char c : str) {int idx = c - 'a'; // 获取在指针数组中的索引if (curr.nexts[idx] == null) { // 如果这个位置没有字符节点return false; // 则说明该树中的字符串不以 prefix 为前缀,返回false}curr = curr.nexts[idx]; // 往下一个字符节点移动}return true; // 该树中一定有字符串以prefix为前缀,返回true}
}

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

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

相关文章

使用 Python 处理 Lumerical 导出的 .txt 文件(完结)

使用 Python 处理 Lumerical 导出的 .txt 文件 引言正文以 , 隔开的波长与透射率以 \t 隔开的波长与透射率引言 之前在 添加链接描述 一文中我们已经介绍了如何将 Lumerical 仿真中的 S 参数相关数据导出为 .txt 文件。这里我们来分享如何使用 Python 对这些数据进行处理。 正…

如果国产BI工具也有顶流,它们一定会上榜

在数据驱动的今天&#xff0c;商业智能&#xff08;BI&#xff09;工具已成为企业不可或缺的助手&#xff0c;它们通过强大的数据处理和分析能力&#xff0c;帮助企业洞察市场趋势&#xff0c;优化运营决策。如果BI工具界也有“顶流”&#xff0c;那么奥威BI、帆软BI&#xff0…

原生CSS变量

原生CSS 变量 css中我们可以统一设置 变量 方便页面维护 声明 变量声明的时候&#xff0c;变量名之前加上两根连词线&#xff08;–&#xff09;即可。例如&#xff1a; 声明的变量是有作用域的&#xff0c;比如是在html中声明的变量&#xff0c;那么该变量在html中的任何地方都…

我国甜菜碱行业规模较大 未来行业发展前景较好

我国甜菜碱行业规模较大 未来行业发展前景较好 甜菜碱化学名称三甲基甘氨酸&#xff0c;是一种在动植物体内广泛存在的季铵型生物碱。它具有多种生物学功能&#xff0c;包括渗透调节、甲基供体等&#xff0c;广泛应用于饲料、食品、医药和化妆品等行业。甜菜碱的提取主要来源于…

揭秘SmartEDA:电路仿真软件如何贯穿课前课中课后,助力电子学习新纪元!

在电子设计与自动化的学习道路上&#xff0c;一款强大的电路仿真软件往往能为学生们带来事半功倍的效果。今天&#xff0c;我们就来深入探讨一下SmartEDA这款电路仿真软件在课前、课中、课后的全方位应用&#xff0c;看看它如何助力我们的电子学习步入新纪元&#xff01; 1、课…

直播平台集成美颜工具详解:视频美颜SDK开发指南

本篇文章&#xff0c;小编将详细介绍如何在直播平台中集成美颜工具&#xff0c;帮助开发者更好地理解视频美颜SDK的开发过程。 一、美颜工具的作用和原理 1.1 美颜工具的作用 美颜工具主要用于提升直播视频的画面质量&#xff0c;让主播和观众在镜头前看起来更加美观。这些功…

2024年最新ComfyUI汉化及manager插件安装详解!

前言 在ComfyUI文生图详解中&#xff0c;学习过如果想要安装相应的模型&#xff0c;需要到模型资源网站&#xff08;抱抱脸、C站、魔塔、哩布等&#xff09;下载想要的模型&#xff0c;手动安装到ComfyUI安装目录下对应的目录中。 为了简化这个流程&#xff0c;我们需要安装Co…

MacOS下更新curl

苹果自带的curl不支持Https&#xff0c;我们可以通过curl -V看到如下结果 curl 7.72.0 (x86_64-apple-darwin18.6.0) libcurl/7.72.0 zlib/1.2.12 libidn2/2.3.7 librtmp/2.3 Release-Date: 2020-08-19 Protocols: dict file ftp gopher http imap ldap ldaps pop3 rtmp rtsp …

Linux workqueue介绍

Linux中的workqueue机制就是为了简化内核线程的创建。通过调用workqueue的接口就能创建内核线程。并且可以根据当前系统的CPU的个数创建线程的数量&#xff0c;使得线程处理的事务能够并行化。 工作队列&#xff08;workqueue&#xff09;是另外一种将工作推后执行的形式。工作…

04:C语言流程控制

C语言流程控制 1、选择结构1.1、第一种&#xff1a;if ...else / if ...else if...else1.2、第二种&#xff1a;switch case 2、循环结构2.1、第一种&#xff1a;for循环2.1、第二种&#xff1a;while循环2.2、第三种&#xff1a;do...while循环 在C语言程序里&#xff0c;一共…

为什么要考数据库证书?

考取数据库证书有多方面的理由和好处&#xff0c;这些好处不仅限于个人职业发展&#xff0c;也涉及到提升专业技能、增强竞争力以及获得行业认可等方面。以下是一些主要的原因&#xff1a; 提升专业技能&#xff1a;数据库证书考试通常要求考生掌握一定的数据库理论知识和实践技…

Java数据结构9-排序

1. 排序的概念及引用 1.1 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录…

【vuejs】vue-router多层级路由配置以及页面嵌套的处理

1. 多层级页面嵌套概念 1.1 什么是多层级页面嵌套 多层级页面嵌套指的是在单页面应用&#xff08;SPA&#xff09;中&#xff0c;页面结构由多个嵌套的组件组成&#xff0c;每个组件可能代表不同的页面或页面区域。这种结构允许开发者将应用组织成多个模块&#xff0c;每个模…

认证资讯|Bluetooth SIG认证

在当今高度互联的世界中&#xff0c;无线技术的普及已经成为我们生活和工作中不可或缺的一部分。作为领先的无线通信技术之一&#xff0c;Bluetooth技术以其稳定性、便捷性和广泛的应用场景而备受青睐。然而&#xff0c;要想在激烈的市场竞争中脱颖而出&#xff0c;获得Bluetoo…

6、Redis系统-数据结构-04-Hash

四、哈希表&#xff08;Hashtable&#xff09; 哈希表是一种高效的键值对数据结构&#xff0c;通过散列函数将键映射到表中的位置&#xff0c;实现快速的插入、删除和查找操作。Redis 广泛使用哈希表来实现 Hash 对象和数据库的键值存储。以下将从结构设计、哈希冲突与链式哈希…

深入源码,探究#、$号替换符的区别

在Mybatis的日常使用过程中以及在一些技术论坛上我们都能常常听到&#xff0c;不要使用$符号来进行SQL的编写&#xff0c;要使用#符号&#xff0c;否则会有SQL注入的风险。那么&#xff0c;为什么在使用$符号时会有注入的风险呢&#xff0c;以及#号为什么不会有风险呢&#xff…

C/C+++服务器之libuv的使用实战

libuv libuv简介 1: 开源跨平台的异步IO库, 主要功能有网络异步&#xff0c;文件异步等。 2: libuv主页: http://libuv.org/ 3: libuv是node.js的底层库; 4: libuv的事件循环模型: epoll, kqueue, IOCP, event ports; 异步 TCP 与 UDP sockets; DNS 解析 异步文件读写; 信号处…

Python结合MobileNetV2:图像识别分类系统实战

一、目录 算法模型介绍模型使用训练模型评估项目扩展 二、算法模型介绍 图像识别是计算机视觉领域的重要研究方向&#xff0c;它在人脸识别、物体检测、图像分类等领域有着广泛的应用。随着移动设备的普及和计算资源的限制&#xff0c;设计高效的图像识别算法变得尤为重要。…

设计模式-结构型-08-组合模式

文章目录 1、学校院系展示需求2、组合模式基本介绍3、组合模式示例3.1、 解决学校院系展示&#xff08;透明模式1&#xff09;3.2、高考的科目&#xff08;透明模式2&#xff09;3.3、高考的科目&#xff08;安全组合模式&#xff09; 4、JDK 源码分析5、注意事项和细节 1、学校…

存储过程编程-创建(CREATE PROCEDURE)、执行(EXEC)、删除(DROP PROCEDURE)

一、定义 1、存储过程是在SQL服务器上存储的已经编译过的SQL语句组。 2、存储过程分为三类&#xff1a;系统提供的存储过程、用户定义的存储过程和扩展存储过程 &#xff08;1&#xff09;系统提供的存储过程&#xff1a;在安装SQL Server时&#xff0c;系统创建了很多系统存…