LeetCode 4, 92, 155

目录

  • 4. 寻找两个正序数组的中位数
    • 题目链接
    • 标签
    • 思路
    • 代码
  • 92. 反转链表 II
    • 题目链接
    • 标签
    • 思路
      • 反转部分链表
      • 寻找 prev
      • 为什么使用 sentinel
    • 代码
  • 155. 最小栈
    • 题目链接
    • 标签
    • 思路
      • 栈的实现
      • 最小值的实现
    • 代码

4. 寻找两个正序数组的中位数

题目链接

4. 寻找两个正序数组的中位数

标签

数组 二分查找 分治

思路

本题是 十分困难 的,如果比较忙,可以跳过本题。

本题难点在于如何保证时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn),显然要使用 二分法,不过应该如何使用 二分法 呢?对于有奇数个 (偶数的情况与之类似,不过需要找两个中位数,求平均值) 元素的合并后的升序数组,可以这样想:求中位数就是求中间元素,即求合并后的数组中第 k = (nums1.length + nums2.length) / 2 + 1 个数,那么可以分别在两个数组中取 k / 2 个数,根据情况进行讨论:

  • 如果 nums1[k / 2] < nums1[k / 2],又因为 nums1 是升序的,所以 nums1 的区间 [ 0 , k 2 ] [0, \frac{k}{2}] [0,2k] 之内的所有元素都只能是 k 个数,这个区间中不存在 k个数,舍弃这个区间;
  • 如果 nums1[k / 2] > nums1[k / 2],又因为 nums2 是升序的,所以 nums2 的区间 [ 0 , k 2 ] [0, \frac{k}{2}] [0,2k] 之内的所有元素都只能是 k 个数,这个区间中不存在 k个数,舍弃这个区间;
  • 如果 nums1[k / 2] == nums2[k / 2],则可以任意将这种情况合并到第一种情况和第二种情况中。

如果能理解这一点,则走出了第一步,剩下的步骤与第一步类似,这里就不做赘述了,请看下面这张图,其中描述了如何寻找“合并后”的数组中的左中位数:
alt text
看完这张图之后肯定会觉得莫名其妙,可以直接看代码,其中有一个 获取 “合并后”的升序数组中 的第 k 个元素 的方法,这张图就是用于描述这个方法的 常规流程 的。至于 idx1idx2 到边界的情况,请看下面这张图:
alt text

代码

class Solution {public double findMedianSortedArrays(int[] nums1, int[] nums2) {int len1 = nums1.length, len2 = nums2.length;int totalLen = len1 + len2;if (totalLen % 2 == 1) { // 如果 两个数组合并的数组的长度 为奇数int midIndex = totalLen / 2; // 获取 中间元素 的索引double median = getKthEle(nums1, nums2, midIndex + 1);return median;} else { // 如果 两个数组合并的数组的长度 为偶数int midLIndex = totalLen / 2 - 1, // 获取 中间偏左的元素 的索引midRIndex = totalLen / 2; // 获取 中间偏右的元素 的索引double median = (getKthEle(nums1, nums2, midLIndex + 1)+ getKthEle(nums1, nums2, midRIndex + 1)) / 2.0; // 求两个中间元素的平均值return median;}}// 获取 “合并后”的升序数组中 的第 k 个元素private int getKthEle(int[] nums1, int[] nums2, int k) {int len1 = nums1.length, len2 = nums2.length;int idx1 = 0, idx2 = 0; // idx1, idx2 分别为 nums1, nums2 的索引while (true) {if (idx1 == len1) { // 如果 idx1 到边界了,说明 nums1 中的元素全被舍弃了return nums2[idx2 + k - 1]; // 则返回 nums2 中的元素}if (idx2 == len2) { // 如果 idx2 到边界了,说明 nums2 中的元素全被舍弃了return nums1[idx1 + k - 1]; // 则返回 nums1 中的元素}if (k == 1) { // 如果 k == 1 了,则此时返回 nums1[idx1] 和 nums2[idx2] 中的较小值作为结果return Math.min(nums1[idx1], nums2[idx2]);}int half = k >> 1; // 获取 k 除以 2 的结果int newIdx1 = Math.min(idx1 + half, len1) - 1; // 获取新的 idx1,并防止越界int newIdx2 = Math.min(idx2 + half, len2) - 1; // 获取新的 idx2,并防止越界int discard; // 被舍弃的元素个素if (nums1[newIdx1] <= nums2[newIdx2]) { // 如果 nums1 中指定索引的元素 <= nums2 中指定索引的元素discard = newIdx1 - idx1 + 1; // 舍弃的元素个数为 索引之差 + 1idx1 = newIdx1 + 1; // 舍弃 nums1 的区间 [idx1, newIdx1] 内的元素} else { // 否则 nums1 中指定索引的元素 > nums2 中指定索引的元素discard = newIdx2 - idx2 + 1; // 舍弃的元素个数为 索引之差 + 1idx2 = newIdx2 + 1; // 舍弃 nums2 的区间 [idx2, newIdx2] 内的元素}k -= discard; // 舍弃元素}}
}

92. 反转链表 II

题目链接

92. 反转链表 II

标签

链表

思路

反转部分链表

alt text
如上图,反转链表就是上面的这些操作。

寻找 prev

不过在进行如上操作之前先要获取 prev,其实不难,只需要让 prev 从 哨兵节点sentinel 开始移动 left - 1 次。例如上图,left = 2,所以 prevsentinel 开始移动 2 - 1 = 1 次即可。

为什么使用 sentinel

如果没有写过链表类似的题目,一上来就看到 哨兵节点sentinel 可能会有些懵,实际上 sentinel 是为了处理 left = 1 的情况而存在的。在 left = 1 的情况下,prev 就没有办法指向一个具体的节点,这时如果给链表添加一个 哨兵节点sentinel,那么 prev 可以指向 sentinel,从而保证反转操作能够正确执行。

代码

class Solution {public ListNode reverseBetween(ListNode head, int left, int right) {ListNode sentinel = new ListNode(0, head); // 使用哨兵节点可以处理 left == 1 的情况ListNode prev = sentinel;// 让 prev 移动 left - 1 次,移动到第 left 个节点的前一个节点处for (int i = 0; i < left - 1; i++) {prev = prev.next;}ListNode oldHead = prev.next; // 待反转 的部分链表的头部for (int i = left; i < right; i++) { // 反转 right - left 次ListNode next = oldHead.next; // 获取 oldHead 的下一个节点 nextoldHead.next = next.next; // oldHead 指向 next 的下一个节点next.next = prev.next; // next 指向 oldHeadprev.next = next; // prev 指向 next}return sentinel.next; // 返回哨兵节点指向的链表}
}

155. 最小栈

题目链接

155. 最小栈

标签

栈 设计

思路

栈的实现

栈这种数据结构不难实现,使用链表即可实现,本题可以通过实现一个栈来解决。

栈是 特殊的链表,特殊之点在于它不需要访问链表中的其他元素,只需要访问链表的尾节点。可以采用 倒序链表 的方式来实现栈,记录栈顶元素 top (即 链表的尾节点) 即可。对于添加新节点,有以下两种情况:

  • 如果栈顶元素 topnull,则将 新节点 放到栈顶元素 top 的位置。
  • 如果栈顶元素 top 不为 null,则让新元素指向原先的栈顶元素,然后让栈顶指针指向新元素。

下图演示了上述的添加过程:
alt text

最小值的实现

本题还要求能够返回栈中的最小值,这并不难实现。如果没有限制时间复杂度为常数级的话,可以遍历链表,来找最小值。不过本题限制了常数级的时间复杂度,这里就需要使用 空间换时间 的思想:将节点压入栈后的最小值存储到当前节点中。这样一来,要获取栈中的最小值,只需要获取栈顶元素的 最小值属性 即可。

代码

class MinStack {// 放到栈里面的节点的数据类,存储 当前元素的值 和 当前栈中的最小元素,此外还有指向下一个节点的指针private static class Node {int val;int min;Node next;Node(int val, int min) {this.val = val;this.min = min;}}private Node top; // 保存链表的尾节点,即记录栈顶元素public MinStack() {}public void push(int val) {if (top == null) { // 如果 栈顶 为空// 则 当前元素 就是 栈中的最小值top = new Node(val, val); // 将 当前元素 作为 栈顶元素} else { // 如果 栈顶 不为空// 则选取 栈顶元素的最小值 和 当前元素 中的较小值作为 加入当前元素后的 栈中的 最小值int min = Math.min(top.min, val);Node newTop = new Node(val, min);newTop.next = top; // 让 新的栈顶元素 指向 原来的栈顶元素top = newTop; // 将 当前元素 作为 新的栈顶元素}}public void pop() {if (top == null) { // 如果 栈顶 为空return; // 则不进行操作,最好报错,这里就直接返回了}top = top.next; // 将 栈顶元素 弹出栈}public int top() {return top.val; // 返回 栈顶元素 的值}public int getMin() {return top.min; // 返回 栈顶元素 的最小值}
}

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

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

相关文章

Qt类 | QPushButton类详解

文章目录 一、QPushButton介绍二、Properties&#xff08;属性&#xff09;三、Public Functions&#xff08;公共函数&#xff09;1.构造函数--构造按钮对象2.autoDefault与setAutoDefault函数--获取/设置按钮的自动默认状态3.isDefault与setDefault函数-- 获取/设置按钮的默认…

服务器的80和443端口关闭也能申请SSL证书

一、简介 在服务器的80和443端口关闭的情况下&#xff0c;确实可以申请SSL证书&#xff0c;但申请过程和方法会根据证书类型和验证方式的不同而有所差异。 通常如果是网站域名申请SSL证书&#xff0c;哪怕服务器的80、443端口都打不开&#xff0c;也可以通过DNS解析的方式来验…

【bypy】服务器代码定期同步到百度网盘

☆ 服务器代码定期同步到百度网盘 - 问题描述 代码的备份是一个重要的事情&#xff0c;可能经常会换服务器&#xff0c;也可能服务器会崩溃。这里教如何将代码同步到百度网盘。当然&#xff0c;智能同步到百度网盘指定的apps目录下 ★ 解决方案 step1. 安装bypy库 首先要确保…

Qt Style Sheets-设计器集成

设计器集成 Qt Designer&#xff08;Qt Designer&#xff09;是一个出色的工具&#xff0c;用于预览样式表。您可以在 Designer 中右键单击任何小部件&#xff0c;并选择“更改样式表...”来设置样式表。 在 Qt 4.2 及更高版本中&#xff0c;Qt Designer 还包括一个样式表语法…

layui 让table里的下拉框不被遮挡

记录&#xff1a;layui 让table里的下拉框不被遮挡 /* 这个是让table里的下拉框不被遮挡 */ .goods_table .layui-select-title,.goods_table .layui-select-title input{line-height: 28px;height: 28px; }.goods_table .layui-table-cell {overflow: visible !important; }.…

API取数实战:企业微信API取数教程

在数字化时代&#xff0c;企业微信不仅是一个通讯工具&#xff0c;更是企业数字化转型的重要平台。通过企业微信&#xff0c;企业能够高效连接员工、客户与合作伙伴&#xff0c;实现内部流程的自动化和智能化。本文将介绍企业微信API的应用场景和应用难点&#xff0c;并提供企业…

新发布,CAISP到底是啥?值得考吗

最近&#xff0c;百度旗下的“萝卜快跑”无人网约车引发热议&#xff0c;有很多人对其持欢迎态度&#xff0c;认为无人驾驶出租车价格低、服务好&#xff0c;不用担心司机车内抽烟&#xff0c;不用害怕司机路怒斗气&#xff0c;司乘矛盾没了&#xff0c;下雨天没人接单的麻烦也…

Java web从入门到精通 (第 2版)中文电子版

前言 《Java Web从入门到精通&#xff08;第2版&#xff09;》共分21章&#xff0c;包括Java Web应用开发概述、HTML与CSS网页开发基础、JavaScript脚本语言、搭建开发环境、JavaBean技术、Servlet技术、过滤器和监听器、Hibernate高级应用、Java Web的数据库操作、EL&#xf…

安卓手机如何恢复删除的照片?一篇文章,3个方法就够了

在这个手机摄影盛行的时代&#xff0c;我们的安卓手机早已不仅仅是一个通讯工具&#xff0c;更是记录生活、珍藏回忆的“时光机”。然而&#xff0c;生活中总有些“小插曲”让人哭笑不得——误删照片。安卓手机如何恢复删除的照片&#xff1f;别急&#xff0c;今天这篇文章就来…

代发考试战报:上海考试HCIP-Cloud Service SA云服务H13-821 ,667分险过

代发考试战报&#xff1a;7月9号上海考试HCIP-Cloud Service SA云服务H13-821 &#xff0c;667分险过&#xff0c;考试当天上午10点买的题库&#xff0c;临阵磨枪&#xff0c;看了俩小时&#xff0c; 12点去考试的&#xff0c;刚及格&#xff0c;幸好题库准&#xff0c;一天看题…

17_Shell好用工具:awk

17_Shell好用工具&#xff1a;awk grep&#xff1a;查找 sed&#xff1a;编辑 cut&#xff1a;切割 awk&#xff1a;切割 可以通过定义变量、流程控制进行深度分析加工 一、awk内置变量 内置变量列出了几个常用的 内置变量含义FILENAME文件名NFNumber Of Fields&#xff0c;单…

自己调用yolov5模型进行前向推理时的报错

当我在自己的工程中调用yolov5的目标检测模型进行推理&#xff0c;代码大致如图&#xff1a; 当运行到如图箭头所指的位置的时候报如下错误&#xff1a; Traceback (most recent call last): File “/home/yons/train/code/mmpose/inference.py”, line 81, in pred yolo_m…

Windows 11预览补丁KB5040527影响火绒驱动加载的解决办法

7 月 11 日&#xff0c;微软更新Windows 11 预览版本补丁 KB5040527&#xff0c;补丁安装后会影响火绒驱动加载导致火绒安全软件服务异常&#xff0c;补丁相关信息如下&#xff1a; https://blogs.windows.com/windows-insider/2024/07/11/releasing-windows-11-builds-22621-…

知识图谱和 LLM:利用Neo4j驾驭大型语言模型(探索真实用例)

这是关于 Neo4j 的 NaLLM 项目的一篇博客文章。这个项目是为了探索、开发和展示这些 LLM 与 Neo4j 结合的实际用途。 2023 年,ChatGPT 等大型语言模型 (LLM) 因其理解和生成类似人类的文本的能力而风靡全球。它们能够适应不同的对话环境、回答各种主题的问题,甚至模拟创意写…

blender使用(三)常用建模操作及修改器

1&#xff0c;挤出图形 tab编辑模式&#xff0c;选中一个点/线/面&#xff0c;按键E&#xff0c;可以挤出对应的图形。选中点会挤出一条线&#xff0c;线会挤出一个面&#xff0c;面挤出体 2&#xff0c;倒角 选中一个边后&#xff0c;ctrlB &#xff0c;拖动鼠标是倒角范围&am…

破解反爬虫策略 /_guard/auto.js(一) 原理

背景 当用代码或者postman访问一个网站的时候&#xff0c;访问他的任何地址都会返回<script src"/_guard/auto.js"></script>&#xff0c;但是从浏览器中访问显示的页面是正常的&#xff0c;这种就是网站做了反爬虫策略。本文就是带大家来破解这种策略&…

C/C++ 关机整人代码

目录 &#x1f4d2;温馨提示 &#x1f4d2;示例代码 &#x1f4d2;代码分析 &#x1f680;欢迎互三&#x1f449;&#xff1a;程序猿方梓燚 &#x1f48e;&#x1f48e; &#x1f680;关注博主&#xff0c;后期持续更新系列文章 &#x1f680;如果有错误感谢请大家批评指出&…

深入浅出消息队列----【初始篇】

深入浅出消息队列----【初始篇】 一、思考&#xff1a;为什么会出现 “消息队列”二、RocketMQ 总览producerproducer groupnameSrvBrokerBroker clusterconsumerconsumer groupTopicTag 本文仅是文章笔记&#xff0c;整理了原文章中重要的知识点、记录了个人的看法 文章来源&a…

linux下Jenkins的安装部署

前言&#xff1a; 用docker安装Jenkins非常方便快捷&#xff0c;但是最近国内的docker镜像源都不好用了&#xff0c;这里回顾一下最原始的Jenkins安装方式 安装前准备 安装环境 Jenkins的运行依赖java环境&#xff0c;linux下jdk的安装参考&#xff1a;linux下JDK的安装-CSD…

有效、轻松地从 SD 卡恢复已删除照片的教程

“我拿到了新手机&#xff0c;并将 SD 卡设置为保存手机拍摄的照片的位置&#xff1b;但是&#xff0c;我错误地删除了 SD 卡上的某些高清照片&#xff0c;如何从 SD 卡恢复已删除的照片&#xff1f;请帮忙。” 除了意外删除之外&#xff0c;许多因素都可能导致 SD 卡上的照片…