力扣大厂热门面试算法题 21-23

        21. 合并两个有序链表,22. 括号生成,23. 合并 K 个升序链表,每题做详细思路梳理,配套Python&Java双语代码, 2024.03.13 可通过leetcode所有测试用例。

目录

21. 合并两个有序链表

解题思路

完整代码

Java

Python

22. 括号生成

解题思路

完整代码

Java

Python

23. 合并 K 个升序链表

解题思路

完整代码

Java

Python


21. 合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例 1:

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例 2:

输入:l1 = [], l2 = []
输出:[]

示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

提示:

  • 两个链表的节点数目范围是 [0, 50]
  • -100 <= Node.val <= 100
  • l1 和 l2 均按 非递减顺序 排列

解题思路

        要合并两个升序链表为一个新的升序链表,我们可以使用一个指针追踪两个链表的当前节点,并比较它们的值以决定哪一个节点应该先被加入到新链表中。一旦我们选中一个节点,我们就将其添加到新链表的末尾,并移动对应链表的指针到下一个节点。重复这个过程直到所有节点都被检查过。

解题思路如下:

  1. 创建一个哨兵(dummy)节点,它将作为新链表的起始节点,这样可以简化插入逻辑并最终返回合并后的链表。
  2. 维持一个当前节点指针,初始指向哨兵节点。
  3. 在两个链表都非空的情况下,比较两个链表当前节点的值。将较小值的节点接在当前节点之后,并将该链表的指针后移。
  4. 如果一个链表变为空,直接将另一个链表的剩余部分接在当前链表之后。
  5. 最终,哨兵节点的下一个节点即为合并后链表的头节点。

完整代码

Java

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
public class Solution {public ListNode mergeTwoLists(ListNode l1, ListNode l2) {// 创建哨兵节点ListNode dummy = new ListNode(-1);// 当前节点指针初始化指向哨兵节点ListNode current = dummy;// 遍历两个链表,直到至少一个链表为空while (l1 != null && l2 != null) {// 比较两个链表当前节点的值,选择较小者加入到新链表中if (l1.val < l2.val) {current.next = l1;l1 = l1.next;} else {current.next = l2;l2 = l2.next;}current = current.next;}// 将非空链表的剩余部分接在新链表的末尾current.next = l1 != null ? l1 : l2;// 哨兵节点的下一个节点即为合并后链表的头节点return dummy.next;}
}

Python

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:# 创建哨兵节点dummy = ListNode(-1)# 当前节点指针初始化指向哨兵节点current = dummy# 遍历两个链表,直到至少一个链表为空while list1 and list2:# 比较两个链表当前节点的值,选择较小者加入到新链表中if list1.val < list2.val:current.next = list1list1 = list1.nextelse:current.next = list2list2 = list2.nextcurrent = current.next# 将非空链表的剩余部分接在新链表的末尾current.next = list1 if list1 else list2# 哨兵节点的下一个节点即为合并后链表的头节点return dummy.next

22. 括号生成

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例 1:

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

示例 2:

输入:n = 1
输出:["()"]

提示:

  • 1 <= n <= 8

解题思路

这个问题是一个经典的回溯算法问题,关键在于如何确保在任何时刻插入的括号序列都是有效的。

解题思路如下:

  1. 初始化:结果集合 res 用于存储所有有效的括号组合。
  2. 递归函数:定义一个递归函数 generate,它接受当前的括号字符串 current,以及两个计数器 openclose 分别表示已放置的左括号和右括号数量。
  3. 递归终止条件:当 current 字符串长度达到 2 * n 时,表示形成了一个完整的括号组合,将其添加到结果集 res 中,并返回。
  4. 递归逻辑
    • 如果 open 小于 n,可以添加一个左括号,并递归调用 generate
    • 如果 close 小于 open,可以添加一个右括号,并递归调用 generate

完整代码

Java

public class Solution {public List<String> generateParenthesis(int n) {List<String> res = new ArrayList<>();backtrack(res, "", 0, 0, n);return res;}private void backtrack(List<String> res, String current, int open, int close, int max) {if (current.length() == max * 2) {res.add(current);return;}if (open < max) {backtrack(res, current + "(", open + 1, close, max);}if (close < open) {backtrack(res, current + ")", open, close + 1, max);}}public static void main(String[] args) {Solution solution = new Solution();List<String> result = solution.generateParenthesis(3);System.out.println(result);}
}

Python

class Solution:def generateParenthesis(self, n: int) -> List[str]:def backtrack(s='', left=0, right=0):if len(s) == 2 * n:res.append(s)returnif left < n:backtrack(s+'(', left+1, right)if right < left:backtrack(s+')', left, right+1)res = []backtrack()return res

23. 合并 K 个升序链表

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[1->4->5,1->3->4,2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

示例 2:

输入:lists = []
输出:[]

示例 3:

输入:lists = [[]]
输出:[]

解题思路

        这个问题的关键在于如何有效地合并多个已排序的链表。一种方法是使用最小堆(优先队列)来保持跟踪每个链表的当前最小节点,从而以线性时间复杂度合并链表。这个解决方案的基本步骤如下:

  1. 初始化最小堆:首先,创建一个最小堆,用于存储每个链表的当前最小节点。堆中的每个元素都是一个节点及其来源链表的索引。

  2. 填充堆:遍历链表数组,将每个链表的头节点插入到最小堆中。这样,堆中始终保持有每个链表当前的最小节点。

  3. 合并链表:创建一个虚拟头节点 dummy,以及一个指向当前合并链表末尾的指针 tail。然后,不断从最小堆中取出最小节点,添加到 tail 的后面,并将该节点的下一个节点(如果存在)插入到最小堆中。重复这个过程,直到堆为空。

  4. 返回结果:返回 dummy 的下一个节点,即合并后链表的头节点。

完整代码

Java

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/public class Solution {public ListNode mergeKLists(ListNode[] lists) {if (lists == null || lists.length == 0) return null;PriorityQueue<ListNode> pq = new PriorityQueue<>((a, b) -> a.val - b.val);for (ListNode list : lists) {if (list != null) {pq.add(list);}}ListNode dummy = new ListNode(0);ListNode tail = dummy;while (!pq.isEmpty()) {tail.next = pq.poll();tail = tail.next;if (tail.next != null) {pq.add(tail.next);}}return dummy.next;}
}

Python

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
from queue import PriorityQueue
class Solution:def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:dummy = ListNode()current = dummypq = PriorityQueue()for i, node in enumerate(lists):if node:pq.put((node.val, i, node))while not pq.empty():val, i, node = pq.get()current.next = nodecurrent = current.nextif node.next:pq.put((node.next.val, i, node.next))return dummy.next

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

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

相关文章

linuxOPS基础_vmware虚拟机安装及介绍

虚拟机概念 什么是虚拟机&#xff1f; 虚拟机&#xff0c;有些时候想模拟出一个真实的电脑环境&#xff0c;碍于使用真机安装代价太大&#xff0c;因此而诞生的一款可以模拟操作系统运行的软件。 虚拟机目前有2 个比较有名的产品&#xff1a;vmware 出品的vmware workstatio…

java-双列集合

什么是双列集合&#xff1f; 集合中每次存的数据是成对存入的 以及它的特点是什么&#xff1f; 特别注意&#xff1a;键不可重复&#xff0c;值可以 Map是双列集合的顶层接口 Map 它有哪些方法呢&#xff1f; Map的常用API 添加 添加操作的代码如下 我们要明白一些细节&…

11. 搭建较通用的GoWeb开发脚手架

文章目录 导言一、加载配置二、初始化日志三、初始化MySQL连接四、初始化Redis连接五、初始化gin框架内置的校验器使用的翻译器六、注册路由七、 启动服务八、测试运行九&#xff1a;注意事项 代码地址&#xff1a;https://gitee.com/lymgoforIT/bluebell 导言 有了前述知识的…

【JavaScript】数据类型转换 ① ( 隐式转换 和 显式转换 | 常用的 数据类型转换 | 转为 字符串类型 方法 )

文章目录 一、 JavaScript 数据类型转换1、数据类型转换2、隐式转换 和 显式转换3、常用的 数据类型转换4、转为 字符串类型 方法 一、 JavaScript 数据类型转换 1、数据类型转换 在 网页端 使用 HTML 表单 和 浏览器输入框 prompt 函数 , 接收的数据 是 字符串类型 变量 , 该…

linux服务器域名解析失败解决

问题 帮实验室师妹解决安装compressai时&#xff0c;域名解析出错 直接ping百度的域名报错域名暂时无法解析 解决方法 这个问题可能是dns域名解析出错&#xff0c;无法访问外网 首先访问resolv.conf文件 sudo vim /etc/resolv.conf然后在最后加上两行 nameserver 114.114…

WPS 云文档保存在本地的地址如何从c盘更改为其他盘?

程序代码园发文地址&#xff1a;WPS 云文档保存在本地的地址如何从c盘更改为其他盘&#xff1f;-程序代码园小说,Java,HTML,Java小工具,程序代码园,http://www.byqws.com/ ,WPS 云文档保存在本地的地址如何从c盘更改为其他盘&#xff1f;http://www.byqws.com/blog/3146.html?…

软件设计师15--进程资源图

软件设计师15--进程资源图 考点1&#xff1a;进程资源图例题&#xff1a; 考点1&#xff1a;进程资源图 例题&#xff1a; 1、在如下所示的进程资源图中&#xff0c;D&#xff09;。 A、P1、P2、P3都是非阻塞节点&#xff0c;该图可以化简&#xff0c;所以是非死锁的 B、P1、…

基于java(springboot+mybatis)汽车信息管理系统设计和实现以及文档

基于java(springbootmybatis)汽车信息管理系统设计和实现以及文档 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐…

基于SSH的物流配送管理系统的设计与实现

摘 要 当今社会&#xff0c;物流配送已成为影响经济发展的显著因素。而随着社会信息化发展&#xff0c;建立有效的物流配送管理体系不仅能够减少物流成本&#xff0c;更能够提升工作人员的工作效率与客户的满意度。而基于B/S架构的物流配送管理体系&#xff0c;不仅具有良好的…

一些可以访问gpt的方式

1、Coze扣子是新一代 AI 大模型智能体开发平台。整合了插件、长短期记忆、工作流、卡片等丰富能力&#xff0c;扣子能帮你低门槛、快速搭建个性化或具备商业价值的智能体&#xff0c;并发布到豆包、飞书等各个平台。https://www.coze.cn/ 2、https://poe.com/ 3、插件阿里…

像SpringBoot一样使用Flask - 2.静态资源访问及模版

一、安装并导入 render_template 功能&#xff1a;渲染/加载模板&#xff0c;一般是html页面 参数&#xff1a;函数的第一个参数是模板的文件名&#xff0c;必填&#xff0c;后面的参数都是键值对&#xff0c;表示模板中变量对应的值&#xff0c;非必填 (不填界面也不会展示成变…

工程管理系统功能设计与实践:实现高效、透明的工程管理

在现代化的工程项目管理中&#xff0c;一套功能全面、操作便捷的系统至关重要。本文将介绍一个基于Spring Cloud和Spring Boot技术的Java版工程项目管理系统&#xff0c;结合Vue和ElementUI实现前后端分离。该系统涵盖了项目管理、合同管理、预警管理、竣工管理、质量管理等多个…

django学习记录07——订单案例(复选框+ajax请求)

1.订单的数据表 1.1 数据表结构 1.2 数据表的创建 models.py class Order(models.Model):"""订单号"""oid models.CharField(max_length64, verbose_name"订单号")title models.CharField(max_length64, verbose_name"名称&…

关于手机是否支持h264的问题的解决方案

目录 现象 原理 修改内容 现象 开始以为是手机不支持h264的编码 。机器人chatgpt一通乱扯。 后来检查了下手机&#xff0c;明显是有h264嘛。 终于搞定&#xff0c;不枉凌晨三点起来思考 原理 WebRTC 默认使用的视频编码器是VP8和VP9&#xff0c;WebRTC内置了这两种编码器…

2023年终总结——跌跌撞撞不断修正

目录 一、回顾1.一月&#xff0c;鼓足信心的开始2.二月&#xff0c;焦躁不安3.三月&#xff0c;路还是要一步一步的走4.四月&#xff0c;平平淡淡的前行5.五月&#xff0c;轰轰烈烈的前行6.六月&#xff0c;看事情更底层透彻了7.七月&#xff0c;设计模式升华月8.八月&#xff…

Docker进阶:深入了解容器数据卷

Docker进阶&#xff1a;深入了解容器数据卷 一、前言二、容器数据卷的作用三、容器数据卷的使用方法四、实战--使用docker部署前端项目&#xff08;数据卷挂载&#xff09;4.1 重要&#xff1a;准备工作&#xff0c;先在本地创建挂载目录4.2 启动一个临时的nginx容器&#xff0…

Day37 socket、TCP、UDP

socket类型 流式套接字(SOCK_STREAM) TCP 提供了一个面向连接、可靠的数据传输服务&#xff0c;数据无差错、无重复的发送且按发送顺序接收。内设置流量控制&#xff0c;避免数据流淹没慢的接收方。数据被看作是字节流&#xff0c;无长度限制。 数据报套接字(SOCK_DGRAM) UD…

WEB区块链开发组件 - KLineChart

当我们开发区块链的时候&#xff0c;实现K线可能大家会想到EChart&#xff0c;但是EChart做可能需要耗费大量工作量&#xff0c;实现出来的功能估计也是牵强着用。 这时候&#xff0c;我们可能网上会搜索到TradingView,可是这个组件虽然功能非常强大&#xff0c;但是还是要费事…

数据库规范化设计案例解析

1.介绍 数据库规范化设计是数据库设计的一种重要方法&#xff0c;旨在减少数据库中的冗余数据&#xff0c;提高数据的一致性&#xff0c;确保数据依赖合理&#xff0c;从而提高数据库的结构清晰度和维护效率。规范化设计通过应用一系列的规范化规则&#xff08;或称“范式”&a…

看完让你的RSA提升一个台阶 [GKCTF 2021]RRRRsa

阅读须知: 探索者安全团队技术文章仅供参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作,由于传播、利用本公众号所提供的技术和信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任,如有侵权烦请告知,我们会立即删除…