力扣热门算法题 89. 格雷编码,92. 反转链表 II,93. 复原 IP 地址

89. 格雷编码,92. 反转链表 II,93. 复原 IP 地址,每题做详细思路梳理,配套Python&Java双语代码, 2024.03.24 可通过leetcode所有测试用例。

目录

89. 格雷编码

解题思路

完整代码

Python

Java

92. 反转链表 II

解题思路

完整代码

Python

Java

93. 复原 IP 地址

解题思路

完整代码

Python

Java


89. 格雷编码

n 位格雷码序列 是一个由 2n 个整数组成的序列,其中:

  • 每个整数都在范围 [0, 2n - 1] 内(含 0 和 2n - 1
  • 第一个整数是 0
  • 一个整数在序列中出现 不超过一次
  • 每对 相邻 整数的二进制表示 恰好一位不同 ,且
  • 第一个 和 最后一个 整数的二进制表示 恰好一位不同

给你一个整数 n ,返回任一有效的 n 位格雷码序列 。

示例 1:

输入:n = 2
输出:[0,1,3,2]
解释:
[0,1,3,2] 的二进制表示是 [00,01,11,10] 。
- 00 和 01 有一位不同
- 01 和 11 有一位不同
- 11 和 10 有一位不同
- 10 和 00 有一位不同
[0,2,3,1] 也是一个有效的格雷码序列,其二进制表示是 [00,10,11,01] 。
- 00 和 10 有一位不同
- 10 和 11 有一位不同
- 11 和 01 有一位不同
- 01 和 00 有一位不同

示例 2:

输入:n = 1
输出:[0,1]

解题思路

要生成一个 n 位的格雷码序列,我们可以使用递归的方法。格雷码有一个很有趣的性质,即可以通过 n-1 位的格雷码来生成 n 位的格雷码。这种方法称为反射法,其步骤如下:

  1. 开始于基础情况:当 n = 1 时,格雷码序列是 [0, 1]。
  2. 递归生成 n-1 位的格雷码序列:对于 n > 1,首先生成 n-1 位的格雷码序列。
  3. 复制并反射:将 n-1 位的格雷码序列复制一份,并反转这个副本,以保持相邻数字只有一位二进制差异。
  4. 添加高位 1:在反转的副本序列的每个数字前添加一个高位的 1,而在原始序列的每个数字前添加一个高位的 0(实际上不需要操作,因为默认高位就是0)。
  5. 合并序列:最后将这两个序列合并,得到 n 位的格雷码序列。

完整代码

Python
class Solution:def grayCode(self, n: int) -> List[int]:if n == 0:return [0]# 递归生成 n-1 位的格雷码prev_gray = self.grayCode(n - 1)result = []# 将前一序列的值添加进结果,前面加0(实际不操作,因为默认就是0)result.extend(prev_gray)# 反射并添加高位的1for code in reversed(prev_gray):result.append(code | 1 << (n - 1))return result
Java
class Solution {public List<Integer> grayCode(int n) {List<Integer> result = new ArrayList<>();// 基础情况:n=1if (n == 0) {result.add(0);return result;}// 递归生成 n-1 位的格雷码List<Integer> prevGray = grayCode(n - 1);// 添加低位的格雷码result.addAll(prevGray);// 添加高位的 1 并反射int addNumber = 1 << (n - 1);for (int i = prevGray.size() - 1; i >= 0; i--) {result.add(prevGray.get(i) + addNumber);}return result;}}

92. 反转链表 II

​给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

示例 1:

输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]

示例 2:

输入:head = [5], left = 1, right = 1
输出:[5]

提示:

  • 链表中节点数目为 n
  • 1 <= n <= 500
  • -500 <= Node.val <= 500
  • 1 <= left <= right <= n

进阶: 你可以使用一趟扫描完成反转吗?

解题思路

要在链表中反转从位置 left 到位置 right 的节点,可以通过一次遍历来实现。这个过程大致可以分为以下几个步骤:

  1. 定位到 left:首先,遍历链表直到到达位置 left。我们需要记录这个位置的前一个节点,因为反转之后,left 节点将会连接到 left 前一个节点上。

  2. 反转 left 到 right:从 left 开始,遍历到 right,并在遍历过程中逐个反转节点的指向。我们需要记录 left 节点,因为反转后,它将指向 right 节点之后的节点。

  3. 重连链表:最后,将链表的未反转部分与反转后的部分正确连接起来。

完整代码

Python
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def reverseBetween(self, head: Optional[ListNode], left: int, right: int) -> Optional[ListNode]:if not head or left == right:return headdummy = ListNode(0, head)prev = dummy# Step 1: 定位到 left 的前一个节点for _ in range(left - 1):prev = prev.next# Step 2: 开始反转reverse = Nonecurrent = prev.nextfor _ in range(right - left + 1):next_temp = current.nextcurrent.next = reversereverse = currentcurrent = next_temp# Step 3: 重连链表prev.next.next = currentprev.next = reversereturn dummy.next
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; }* }*/
class Solution {public ListNode reverseBetween(ListNode head, int left, int right) {if (head == null || left == right) {return head;}ListNode dummy = new ListNode(0);dummy.next = head;ListNode prev = dummy;// Step 1: 定位到 left 的前一个节点for (int i = 0; i < left - 1; i++) {prev = prev.next;}// Step 2: 开始反转ListNode start = prev.next;ListNode then = start.next;for (int i = 0; i < right - left; i++) {start.next = then.next;then.next = prev.next;prev.next = then;then = start.next;}// Step 3: 链表已经在反转过程中正确连接,不需要额外操作return dummy.next;}
}

93. 复原 IP 地址

有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。

  • 例如:"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址,但是 "0.011.255.245""192.168.1.312" 和 "192.168@1.1" 是 无效 IP 地址。

给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 '.' 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。

示例 1:

输入:s = "25525511135"
输出:["255.255.11.135","255.255.111.35"]

示例 2:

输入:s = "0000"
输出:["0.0.0.0"]

示例 3:

输入:s = "101023"
输出:["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]

提示:

  • 1 <= s.length <= 20
  • s 仅由数字组成

解题思路

生成所有可能的有效 IP 地址,可以通过回溯算法来解决。这个问题的关键在于逐步构建 IP 地址的每一部分,并在每一步中确保该部分是有效的。具体步骤如下:

  1. 定义回溯函数:定义一个回溯函数,该函数接收当前构造的 IP 地址部分、剩余的字符串和已经确定的段数作为参数。

  2. 结束条件:当已经确定了 4 段 IP 地址并且消耗完了输入字符串时,将当前构建的 IP 地址添加到结果集中。

  3. 递归和回溯:从输入字符串中选择 1 到 3 个字符作为当前段的候选,如果选择的字符串是有效的 IP 段(0-255,且无前导 0,除非是单独的 0),则递归地继续选择下一段。

  4. 有效性检查:检查当前选择的字符串是否形成一个有效的 IP 地址段。

  5. 剪枝:在某些情况下提前终止搜索,例如,如果剩余的字符串太长或太短,无法形成有效的剩余段。

完整代码

Python
class Solution:def restoreIpAddresses(self, s: str) -> List[str]:def isValid(segment):# 检查 IP 段的有效性return len(segment) == 1 or (segment[0] != '0' and int(segment) <= 255)def backtrack(start=0, parts=[]):# 如果找到了 4 部分,并且用完了所有字符if len(parts) == 4 and start == len(s):result.append('.'.join(parts))returnif len(parts) == 4 or start == len(s):return# 尝试每一部分的长度:1, 2, 或 3for end in range(start + 1, min(start + 4, len(s) + 1)):segment = s[start:end]if isValid(segment):backtrack(end, parts + [segment])result = []backtrack()return result
Java
public class Solution {public List<String> restoreIpAddresses(String s) {List<String> result = new ArrayList<>();void backtrack(int start, List<String> parts) {if (parts.size() == 4 && start == s.length()) {result.add(String.join(".", parts));return;}if (parts.size() == 4 || start == s.length()) return;for (int end = start + 1; end <= Math.min(start + 3, s.length()); end++) {String segment = s.substring(start, end);if ((segment.length() == 1 || (segment.length() > 1 && segment.charAt(0) != '0')) && Integer.parseInt(segment) <= 255) {parts.add(segment);backtrack(end, new ArrayList<>(parts));parts.remove(parts.size() - 1);}}}backtrack(0, new ArrayList<>());return result;}
}

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

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

相关文章

苹果智能戒指专利获批,Find My功能为智能穿戴提供智能防丢

根据美国商标和专利局&#xff08;USPTO&#xff09;近日公示的清单&#xff0c;苹果公司获得了一项关于智能戒指的专利&#xff0c;展示了多种交互手势&#xff0c;不仅支持捏合、画圈等&#xff0c;而且支持玩“石头剪刀布”游戏。 这项新专利名为“皮肤间接触检测”&#xf…

南京观海微电子---Vitis HLS设计流程介绍——Vitis HLS教程

1. 传统的FPGA设计流程 传统的RTL设计流程如下图所示&#xff1a; 传统的FPGA RTL设计流程主要是采用VHDL、VerilogHDL或System Verilog进行工程的开发&#xff0c;同时也是通过硬件描述语言来编写测试案例&#xff08;Test Bench&#xff09;对开发的工程进行仿真验证。 随后…

基于单片机热电偶智能体温检测系统设计

**单片机设计介绍&#xff0c;基于单片机热电偶智能体温检测系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机热电偶智能体温检测系统设计概要 一、引言 本系统旨在通过单片机实现对人体体温的智能检测&#…

一文教你学会用群晖NAS配置WebDAV服务结合内网穿透实现公网同步Zotero文献库

文章目录 前言1. Docker 部署 Trfɪk2. 本地访问traefik测试3. Linux 安装cpolar4. 配置Traefik公网访问地址5. 公网远程访问Traefik6. 固定Traefik公网地址 前言 Trfɪk 是一个云原生的新型的 HTTP 反向代理、负载均衡软件&#xff0c;能轻易的部署微服务。它支持多种后端 (D…

电缆故障测试仪的原理和组成部件分别是什么?

电缆故障测试仪是专为检测电缆线路中的各种故障而设计制造的精密电子设备&#xff0c;广泛应用于电力、通信、石油化工、航空航天等领域。这类仪器的工作原理和组成相对复杂&#xff0c;下面将详细阐述。 电缆故障测试仪的工作原理 电缆故障测试仪的核心原理通常涉及电磁波反…

【C语言】 gets()puts()fgets()fputs()字符串输入输出函数的用法

文章目录 C语言中的字符串输入输出函数&#xff1a;gets、puts、fgets与fputsgets函数puts函数fgets函数fputs函数 C语言中的字符串输入输出函数知识点总结结语 C语言中的字符串输入输出函数&#xff1a;gets、puts、fgets与fputs 在C语言中&#xff0c;处理字符串的输入和输出…

用系统观念打造智慧公厕,引领智慧城市的发展

智慧公厕&#xff0c;作为智慧城市建设的一部分&#xff0c;具有重要意义。在高度发达的科技条件下&#xff0c;如何打造高质量的智慧公厕是一个值得思考的问题。本文将以智慧公厕源头实力厂家广州中期科技有限公司&#xff0c;大量精品案例项目现场实景实图实例&#xff0c;探…

Java I/O

什么是 IO流&#xff1f; 存储和读取数据的解决方案 I: input O: output 流&#xff1a;像水流一样传输数据 IO流的作用&#xff1f; 用于读写数据&#xff08;本地文件&#xff0c;网络&#xff09; IO流从 传输方式 分类 字符是给人看的&#xff0c;字节是给计算机看的。 …

【SpringBoot】了解简单原理 Bean管理 配置优先级

文章目录 一、配置优先级1.1 命令行设置端口号1.2 打包后修改端口号1.3 优先级 小结 二、Bean的管理2.1 获取Bean2.2 Bean作用域2.3 第三方Bean 三、剖析Springboot的底层原理3.1 起步依赖3.2 自动配置3.2.1 第三方类装配3.2.2 原理分析 总结Web后端开发总结&#xff1a;源码跟…

计算机专业学习单片机有什么意义吗?

玩单片机跟玩计算机区别还是很大的, 单片机有众多的种类,每一种又可能有很多个系列.可以说单片机就是为了专款专用而生的.这样来达到产品成本的降低,这就是现在身边的很多的电子产品价格一降再降的原因之一.在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一…

阅读FAST-LIO2(Lidar-IMU)论文

一、摘要 本文介绍了 FAST-LIO2&#xff1a;一种快速、稳健且通用的 LiDAR 惯性里程计框架。 FASTLIO2 建立在高效紧耦合迭代卡尔曼滤波器的基础上&#xff0c;具有两个关键创新&#xff0c;可实现快速、稳健和准确的 LiDAR 导航&#xff08;和映射&#xff09;。第一个是直接将…

热门主食冻干希喂/PURPOSE/百利测评对比!真实喂养分享!

在当今科学养宠的时代里&#xff0c;主食冻干已经成为猫咪日常饮食的重要一环。主食冻干的高肉含量特性使其易于被猫咪吸收和消化&#xff0c;同时&#xff0c;它还能提供其他猫粮所无法提供的微量物质&#xff0c;满足猫咪的全面营养需求。然而&#xff0c;面对市面上众多品牌…

Java SPI 机制

SPI 机制的定义 在Java中&#xff0c;SPI&#xff08;Service Provider Interface&#xff09;机制是一种用于实现软件组件之间松耦合的方式。它允许在应用程序中定义服务接口&#xff0c;并通过在类路径中发现和加载提供该服务的实现来扩展应用程序功能。 SPI 机制通常涉及三…

信创实力进阶,Smartbi再获华为云鲲鹏技术认证

日前&#xff0c;经华为技术有限公司评测&#xff0c;思迈特商业智能与数据分析软件Smartbi Insight V11与华为技术有限公司Kunpeng 920 Taishan 200完成并通过相互兼容性测试认证&#xff0c;成功再获华为云鲲鹏技术认证书&#xff0c;标志着Smartbi与华为云鲲鹏产业生态合作更…

动态规划相关题目

文章目录 1.动态规划理论基础2.斐波那契数3.爬楼梯4.使用最小花费爬楼梯5.不同路径6.不同路径 II7. 整数拆分8. 不同的二叉搜索树 1.动态规划理论基础 1.1 什么是动态规划? 动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff0c;如果某一…

安卓逆向 | JEB静态分析APK

JEB反编译APK-静态审计&#xff0c;找到加密算法 参考来源&#xff1a;https://blog.csdn.net/weixin_38819889/article/details/108910525 apk来源&#xff1a;https://app5.scrape.center/ 软件&工具&#xff1a;JEB / 雷电模拟器 / burpsuite 声明&#xff1a;scrape.ce…

浅模仿小米商城布局(有微调)

CSS文件 *{margin: 0;padding: 0;box-sizing: border-box; }div[class^"h"]{height: 40px; } div[class^"s"]{height: 100px; } .h1{width: 1528px;background-color: green; } .h11{background-color:rgb(8, 220, 8); } .h111{width: 683px;background-c…

【差分约束+并查集】第十三届蓝桥杯省赛C++ A组 Java A组/研究生组《推导部分和》(C++)

【题目描述】 【输入格式】 【输出格式】 【数据范围】 【输入样例】 5 3 3 1 5 15 4 5 9 2 3 5 1 5 1 3 1 2 【输出样例】 15 6 UNKNOWN 【思路】 题解来源&#xff1a;AcWing 4651. $\Huge\color{gold}{推导部分和}$ - AcWing 【代码】 #include<bits/stdc.h> #define…

PostgreSQL FDW(外部表) 简介

1、FDW: 外部表 背景 提供外部数据源的透明访问机制。PostgreSQL fdw(Foreign Data Wrapper)是一种外部访问接口,可以在PG数据库中创建外部表,用户访问的时候与访问本地表的方法一样,支持增删改查。 而数据则是存储在外部,外部可以是一个远程的pg数据库或者其他数据库(…

基于java+springboot+vue实现的成都旅游网系统(文末源码+Lw+ppt)23-358

摘 要 人类现已迈入二十一世纪&#xff0c;科学技术日新月异&#xff0c;经济、资讯等各方面都有了非常大的进步&#xff0c;尤其是资讯与网络技术的飞速发展&#xff0c;对政治、经济、军事、文化等各方面都有了极大的影响。 利用电脑网络的这些便利&#xff0c;发展一套成…