【LeetCode】234. 回文链表

server/2024/11/14 15:02:49/

回文链表

题目描述:

        给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。

示例 1:

输入:head = [1,2,2,1]
输出:true

示例 2:

输入:head = [1,2]
输出:false

提示:

  • 链表中节点数目在范围[1, 105] 内
  • 0 <= Node.val <= 9

进阶:你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

方法一思路分析:

反转链表的一半

  1. 使用快慢指针找到链表的中点:快指针每次移动两步,慢指针每次移动一步,当快指针到达链表末尾时,慢指针就位于链表的中点(对于奇数个节点的链表,慢指针位于中间两个节点的第一个)。

  2. 反转链表的后半部分:从慢指针开始,反转链表的后半部分。

  3. 比较前后两部分:将反转后的后半部分与原始链表的前半部分进行比较,如果每个节点都相等,则是回文链表

代码实现:

public class Solution {  public boolean isPalindrome(ListNode head) {  // 如果链表为空或只有一个节点,直接返回true  if (head == null || head.next == null) {  return true;  }  // 使用快慢指针找到链表的中点  ListNode slow = head;  ListNode fast = head;  ListNode prev = null;  while (fast != null && fast.next != null) {  prev = slow;  slow = slow.next;  fast = fast.next.next;  }  // 如果链表长度为奇数,则跳过中点  if (fast != null) {  slow = slow.next;  }  // 反转链表的后半部分  ListNode secondHalfHead = reverseList(slow);  // 比较前半部分和反转后的后半部分  ListNode p1 = head;  ListNode p2 = secondHalfHead;  while (p2 != null) {  if (p1.val != p2.val) {  return false;  }  p1 = p1.next;  p2 = p2.next;  }  return true;  }  // 反转链表的方法  private ListNode reverseList(ListNode head) {  ListNode prev = null;  ListNode curr = head;  while (curr != null) {  ListNode nextTemp = curr.next;  curr.next = prev;  prev = curr;  curr = nextTemp;  }  return prev;  }  
}

方法二思路分析:使用栈

        遍历链表,将遍历到的每个节点的值压入栈中。然后,再次遍历链表,同时从栈中弹出元素,比较从链表中取出的元素和从栈中弹出的元素是否相等。如果所有元素都匹配,则链表是回文的。

public class Solution {  public boolean isPalindrome(ListNode head) {  Stack<Integer> stack = new Stack<>();  ListNode curr = head;  // 遍历链表,将值压入栈  while (curr != null) {  stack.push(curr.val);  curr = curr.next;  }  // 再次遍历链表,同时从栈中弹出元素进行比较  curr = head;  while (curr != null) {  if (curr.val != stack.pop()) {  return false;  }  curr = curr.next;  }  return true;  }  
}

方法三思路分析:使用数组

        遍历链表,将遍历到的每个节点的值存储在一个数组中。然后,使用双指针技术(一个从头开始,一个从尾开始)来比较数组中的元素。这种方法的空间复杂度是O(n),其中n是链表的长度。

public class Solution {  public boolean isPalindrome(ListNode head) {  List<Integer> vals = new ArrayList<>();  ListNode curr = head;  // 遍历链表,将值存储在数组中  while (curr != null) {  vals.add(curr.val);  curr = curr.next;  }  // 使用双指针比较数组中的元素  int i = 0, j = vals.size() - 1;  while (i < j) {  if (!vals.get(i).equals(vals.get(j))) {  return false;  }  i++;  j--;  }  return true;  }  
}

http://www.ppmy.cn/server/100119.html

相关文章

如何使用python抽取pdf表格及文本,并保存到excel

pdf是一种便携式文档格式&#xff0c;由Adobe公司设计。因为不受平台限制&#xff0c;且方便保存和传输&#xff0c;所以pdf非常受欢迎。 目前市场上有很多pdf工具&#xff0c;大部分是阅读类&#xff0c;也有支持对pdf的修改、转换等功能&#xff0c;但这部分工具不少是收费的…

Journyx soap_cgi.pyc接口XML外部实体注入漏洞复现 [附POC]

文章目录 Journyx soap_cgi.pyc接口XML外部实体注入漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现Journyx soap_cgi.pyc接口XML外部实体注入漏洞复现 [附POC] 0x01 前言 免责声明:请勿利用文章内的相关技术…

Java设计模式-抽象工厂模式-一次性理解透

1. 抽象工厂模式简介 抽象工厂设计模式是创建型模式之一。抽象工厂模式与工厂模式几乎相似&#xff0c;只是它更像工厂中的工厂。 如果您熟悉Java 中的工厂设计模式&#xff0c;或看过上一篇我写的“java简单工厂模式”&#xff0c;您会注意到我们有一个工厂类。此工厂类根据…

使用python时,数据库有分页,如何实现?

在 Python 中实现数据库分页一般是通过 SQL 查询中的 LIMIT 和 OFFSET 子句来实现的。以下是一个示例&#xff0c;展示如何在 ORM 设计中添加分页功能。 分页实现思路 确定每页记录数&#xff1a;用户可以指定每页显示的记录数量。计算偏移量&#xff1a;根据当前页码和每页记…

2024年第四届智慧城市与绿色能源国际会议(ICSCGE 2024)即将召开!

第四届国际智慧城市与绿色能源会议&#xff08;ICSCGE 2024&#xff09;将于2024年12月10-13日在澳大利亚悉尼举行&#xff0c;会议旨在汇聚来自世界各地的专家学者&#xff0c;共同讨论智慧城市框架及其在可持续发展和绿色能源领域的最新进展和创新成就。ICSCGE是一个致力于探…

SSHamble:SSH 服务的开源安全测试

runZero 发布了有关安全外壳 (SSH) 暴露的新研究&#xff0c;并推出了相应的开源工具 SSHamble。 该工具可帮助安全团队通过测试不常见但危险的错误配置和软件错误来验证 SSH 实施。 发现弱点 在 2024 年美国黑帽大会的演讲中&#xff0c;HD Moore 和 Rob King 分享了这项研…

谷粒商城实战笔记-175~177-商城业务-检索服务-检索查询接口开发

文章目录 一&#xff0c;175-商城业务-检索服务-检索查询参数模型分析抽取二&#xff0c;176-商城业务-检索服务-检索返回结果模型分析抽取三&#xff0c;177-商城业务-检索服务-检索DSL测试-查询部分四&#xff0c;178-商城业务-检索服务-检索DSL测试-聚合部分问题记录解决方案…

场景感知如何做到成为智能时代下的生活新维度

在日新月异的智能科技浪潮中&#xff0c;场景感知正逐步成为连接物理世界与数字世界的桥梁&#xff0c;深刻改变着我们的生活方式与交互体验。场景感知&#xff0c;简而言之&#xff0c;是指智能系统通过多种传感器和数据分析技术&#xff0c;实时理解并适应当前环境及用户状态…