LeetCode题练习与总结:回文链表--234

news/2024/9/23 3:51:49/

一、题目描述

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

示例 1:

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

示例 2:

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

提示:

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

二、解题思路

  1. 快慢指针法找到链表中点:我们可以使用两个指针,快指针每次移动两步,慢指针每次移动一步。当快指针到达链表末尾时,慢指针恰好到达链表中点。

  2. 翻转后半部分链表:当找到链表中点后,我们可以将后半部分链表翻转,以便与前半部分链表进行比较。

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

  4. 恢复链表(可选):如果题目要求不改变原链表结构,我们需要在比较完成后,将后半部分链表再次翻转回来。

三、具体代码

class Solution {public boolean isPalindrome(ListNode head) {// 快慢指针找到链表中点ListNode slow = head, fast = head;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;}// 如果链表长度为奇数,慢指针需要再向前移动一位if (fast != null) {slow = slow.next;}// 翻转后半部分链表ListNode prev = null;ListNode curr = slow;while (curr != null) {ListNode nextTemp = curr.next;curr.next = prev;prev = curr;curr = nextTemp;}// 比较前后两部分链表ListNode firstHalf = head;ListNode secondHalf = prev;while (secondHalf != null) {if (firstHalf.val != secondHalf.val) {return false;}firstHalf = firstHalf.next;secondHalf = secondHalf.next;}return true;}
}

注意:在比较完成后,如果题目没有要求恢复原链表结构,则不需要再次翻转后半部分链表。如果需要恢复,可以在比较完成后,将上述翻转后半部分链表的代码再执行一遍。

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 快慢指针遍历链表:这个步骤中,快指针每次移动两步,慢指针每次移动一步,直到快指针到达链表末尾。在最坏的情况下,快指针会遍历整个链表一次,而链表长度为 n,所以时间复杂度为 O(n)。

  • 翻转后半部分链表:这个步骤中,我们需要遍历链表的后半部分,也就是大约 n/2 个节点,因此时间复杂度为 O(n/2),这可以简化为 O(n)。

  • 比较前后两部分链表:在这个步骤中,我们比较前后两部分链表,每部分大约有 n/2 个节点,因此时间复杂度为 O(n/2),这同样可以简化为 O(n)。

将上述步骤的时间复杂度相加,我们得到总的时间复杂度为 O(n) + O(n) + O(n) = O(n)。

2. 空间复杂度
  • 快慢指针遍历链表:这个步骤中,我们只使用了常数个额外空间(即快慢指针),因此空间复杂度为 O(1)。

  • 翻转后半部分链表:在这个步骤中,我们没有使用额外的数据结构,而是直接在原链表上进行操作,所以空间复杂度仍然是 O(1)。

  • 比较前后两部分链表:这个步骤中,我们也没有使用额外的空间,只是通过指针遍历链表,所以空间复杂度为 O(1)。

将上述步骤的空间复杂度相加,我们得到总的空间复杂度为 O(1) + O(1) + O(1) = O(1)。

综上所述,该算法的时间复杂度为 O(n),空间复杂度为 O(1)。

五、总结知识点

  • 链表(Linked List)

    • 链表是一种常见的基础数据结构,由一系列节点组成,每个节点包含数据域和指向下一个节点的指针。
  • 链表(Singly Linked List)

    • 代码中的链表是单链表,每个节点只包含一个指向下一个节点的指针。
  • 快慢指针(Fast and Slow Pointers)

    • 快慢指针是一种技巧,常用于解决链表中的问题,如查找链表中点、检测环等。快指针每次移动两步,慢指针每次移动一步。
  • 链表翻转(Reversing a Linked List)

    • 代码展示了如何通过迭代的方式翻转链表的一部分。这是通过改变节点指针的方向来实现的。
  • 递归(Recursion)

    • 虽然代码中没有直接使用递归,但翻转链表的过程也可以通过递归来实现。
  • 迭代(Iteration)

    • 代码中使用了迭代(循环)来翻转链表的后半部分以及比较链表的前后两部分。
  • 边界条件处理

    • 在快慢指针寻找中点的过程中,代码处理了链表长度为奇数的情况,确保慢指针正确地指向后半部分链表的第一个节点。
  • 逻辑判断(Logical Comparison)

    • 代码中使用了 if 语句来比较链表前后两部分节点的值,以判断链表是否为回文。
  • 链表节点类定义(ListNode Class Definition)

    • 虽然代码片段中没有给出 ListNode 类的定义,但它是链表实现的基础,通常包含一个数据域和一个指向下一个节点的指针。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。


http://www.ppmy.cn/news/1529135.html

相关文章

【诉讼流程-健身房-违约-私教课-诉讼书提交流程-民事诉讼-自我学习-铺平通往法律的阶梯-讲解(3)】

【诉讼流程-健身房-违约-私教课-诉讼书提交流程-民事诉讼-自我学习-铺平通往法律的阶梯-讲解&#xff08;3&#xff09;】 1、前言说明2、流程说明3、现场提交&#xff08;线下&#xff09;4、网上提交1-起诉书样例2-起诉书编写&#xff08;1&#xff09;原告信息&#xff1a;&…

leetcode:最高乘法得分

用auto可以过 class Solution { public:long long maxScore(vector<int>& a, vector<int>& b) {int n b.size();vector<vector<long long>> memo(4,vector<long long>(b.size(), LLONG_MIN));auto dfs [&](auto&& dfs, i…

认识结构体

目录 一.结构体类型的声明 1.结构的声明 2.定义结构体变量 3.结构体变量初始化 4.结构体的特殊声明 二.结构体对齐(重点难点) 1.结构体对齐规则 2.结构体对齐练习 (一)简单结构体对齐 (二)嵌套结构体对齐 3.为什么存在内存对齐 4.修改默认对齐数 三.结构体传参 1…

KTH5762系列 低功耗、高精度 3D 霍尔角度传感器 电子手表旋钮应用

KTH5762系列 低功耗、高精度 3D 霍尔角度传感器 电子手表旋钮应用 KTH5762AQ3DNE 概述 KTH5762 是一款集成了高度匹配霍尔元件的3D (XY、 XZ 、 YZ 平面 ) 霍尔角度传感器&#xff0c;集成低功 耗&#xff0c;低噪声&#xff0c;高精度零漂运放&#xff0c;高性能&#xff…

IS-Net 教程:基于 PyTorch 的图像分割网络

IS-Net 教程&#xff1a;基于 PyTorch 的图像分割网络 IS-Net&#xff08;Image Structure Network&#xff09;是 DIS 项目 中的核心模块之一&#xff0c;用于进行复杂的图像结构化任务&#xff0c;尤其在图像分割、图像修复、去噪等任务中表现优异。本教程将介绍如何在 PyTo…

MySQL 数据库课程设计详解与操作示例

标题&#xff1a;MySQL 数据库课程设计详解与操作示例 简介 在数据库课程设计中&#xff0c;MySQL 是一个常用的关系型数据库管理系统 (RDBMS)。它以高效、稳定、易用而闻名&#xff0c;广泛应用于网站开发、数据分析和企业级应用中。本文将带你深入了解如何基于 MySQL 完成数…

电脑ip会因为换了网络改变吗

在当今数字化时代&#xff0c;IP地址作为网络世界中的“门牌号”&#xff0c;扮演着至关重要的角色。它不仅是设备在网络中的唯一标识&#xff0c;也是数据交换和信息传递的基础。然而&#xff0c;对于普通用户而言&#xff0c;一个常见的问题便是&#xff1a;当电脑连接到不同…

设计模式中工厂模式的C语言实现

在C语言中实现工厂模式&#xff08;Factory Pattern&#xff09;通常需要模拟面向对象的编程方式。工厂模式的核心思想是通过工厂函数来创建不同类型的对象&#xff0c;隐藏对象创建的细节。下面是一个简单的工厂模式在C语言中的实现。 工厂模式示例&#xff1a;几何形状工厂 …