首页 > 其他分享 >234.回文链表

234.回文链表

时间:2023-10-30 18:23:00浏览次数:31  
标签:pre head next 链表 234 new 节点 回文

目录

题目

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

示例 1:

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

示例 2:

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

法一、复制+反转链表

  • 把原链表翻转一下,与没翻转的链表对比,相同则是回文,返回True,不同则返回False。在进行链表翻转时需要把原链表节点一个一个取下来,用头插法放到新的链表中,导致原链表被拆毁,没法比较了,所以一开始先把原链表复制一份。
class Solution:
    def isPalindrome(self, head: Optional[ListNode]) -> bool:
        if not head or not head.next:#空链表和单个节点链表
            return True

        # 复制链表
        new_head = ListNode(0)#定义复制链表的头节点
        new_current = new_head
        current = head

        while current:#当原链表没到链尾时进行复制
            new_node = ListNode(current.val)#创建一个新的节点,把原链表当前指针所指的值赋与
            new_current.next = new_node#把这个节点加载在新链表
            new_current = new_current.next#新链表的当前指针后移
            current = current.next#原链表的指针后移

        # 反转链表
        new_head2 = ListNode(0)#定义反转链表的头节点
        pre = head#pre指针指向头
        while pre:#当pre没到链表结尾时循环
            cur = pre.next#把pre的下一个指针赋给指针cur
            pre.next = new_head2.next#把新的头节点的next赋给pre的next
            new_head2.next = pre#新的头节点的next指向pre
            pre = cur#更新pre

        # 比较链表是否回文
        i, j = new_head.next, new_head2.next
        while i and j:
            if i.val != j.val:
                return False
            i = i.next
            j = j.next
        return True
  • 时间复杂度为 O(n),空间复杂度为 O(n)

法二、堆栈

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        stack = []#创建一个空栈 stack 用于存储链表节点
        # step1: push 
        curr = head
        while(curr):#遍历链表
            stack.append(curr)#将节点依次压入栈中
            curr = curr.next
        # step2: pop and compare
        node1 = head#链表的当前节点 node1 
        while(stack):
            node2 = stack.pop()#弹出的栈顶元素
            if node1.val != node2.val:
                return False
            node1 = node1.next
        return True
  • 时间复杂度为 O(n),空间复杂度为 O(n)

法三、快慢指针和链表反转

1.使用快慢指针找到链表的中间节点。快指针每次移动两步,慢指针每次移动一步,当快指针到达链表末尾时,慢指针指向的节点即为链表的中间节点。
2.反转链表的后半部分。从中间节点开始,将后半部分链表进行反转操作。
3.比较链表的前半部分和反转后的后半部分。分别使用两个指针同时遍历两部分链表,比较节点的值是否相等。如果所有节点的值都相等,则链表是回文的;否则,链表不是回文的。
4.恢复链表并返回结果。将反转后的后半部分链表再次进行反转操作,使链表恢复原来的顺序。

class Solution:
    def isPalindrome(self, head: Optional[ListNode]) -> bool:
        if not head or not head.next:#空链表和单个节点链表
            return True

        # 找到链表的中间节点
        slow = fast = head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next

        # 反转后半部分链表
        prev = None
        while slow:
            next_node = slow.next
            slow.next = prev
            prev = slow
            slow = next_node

        # 比较链表的前半部分和反转后的后半部分
        p1, p2 = head, prev
        while p1 and p2:
            if p1.val != p2.val:
                return False
            p1 = p1.next
            p2 = p2.next

        # 恢复链表
        prev = None
        while prev != None:
            next_node = p2.next
            p2.next = prev
            prev = p2
            p2 = next_node

        return True
  • 时间复杂度为 O(n),空间复杂度为 O(1)

标签:pre,head,next,链表,234,new,节点,回文
From: https://www.cnblogs.com/lushuang55/p/17797133.html

相关文章

  • 05数据结构(栈、队列、数组、链表)
    数据结构一、什么是数据结构计算机底层存储、组织数据的方式。是指数据相互之间是以什么方式排列在一起的。数据结构是为了更加方便的管理和使用数据,需要结合具体的业务场景来进行选择。一般情况下,精心选择的数据结构可以带来更高的运行或者存储效率。如何学习数据结构:每......
  • 算法题:分别用c++/python/java实现回文数
    回文数是一个数字,从左到右和从右到左读都是相同的数字序列。换句话说,回文数在数值上是对称的。一些常见的回文数示例包括:单个数字:例如1、2、3等,它们本身就是回文数,因为它们只有一个数字。两位数:例如11、22、33等,它们也是回文数,因为它们的左右两个数字相同。多位数:例如121、1331、12......
  • 【算法题】得到K个半回文串的最小修改次数
    题目:给你一个字符串s和一个整数k,请你将s分成k个子字符串,使得每个子字符串变成半回文串需要修改的字符数目最少。请你返回一个整数,表示需要修改的最少字符数目。注意:如果一个字符串从左往右和从右往左读是一样的,那么它是一个回文串。如果长度为len的字符串存在......
  • 21. 合并两个有序链表
    目录题目代码题目将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。示例1:输入:l1=[1,2,4],l2=[1,3,4]输出:[1,1,2,3,4,4]示例2:输入:l1=[],l2=[]输出:[]示例3:输入:l1=[],l2=[0]输出:[0]代码class......
  • 面试必刷TOP101:16、删除有序链表中重复的元素-II
    一、题目二、题解importjava.util.*;publicclassSolution{publicListNodedeleteDuplicates(ListNodehead){//空链表if(head==null)returnnull;ListNoderes=newListNode(0);//在链表前加一个表头......
  • 19. 删除链表的倒数第 N 个结点(中)
    目录题目法一、循环法二、快慢指针题目给你一个链表,删除链表的倒数第n个结点,并且返回链表的头结点。示例1:输入:head=[1,2,3,4,5],n=2输出:[1,2,3,5]示例2:输入:head=[1],n=1输出:[]示例3:输入:head=[1,2],n=1输出:[1]法一、循环classSolution:......
  • #链表#CF706E Working routine
    题目给出一个\(n*m\)的矩阵,每次交换两个等大的矩阵,输出\(q\)次操作后的矩阵分析维护向右和向下的指针,考虑最后输出只需要从每行的头指针向右跳,那么修改实际上是将矩阵左边一列、上面一行、最后一行和最后一列向右下指针交换时间复杂度\(O((n+m)Q)\)代码#include<cs......
  • 237. 删除链表中的节点(中)
    目录题目代码题目有一个单链表的 head,我们想删除它其中的一个节点 node。给你一个需要删除的节点 node 。你将 无法访问 第一个节点  head。链表的所有值都是唯一的,并且保证给定的节点 node 不是链表中的最后一个节点。删除给定的节点。注意,删除节点并不是指从......
  • 代码随想录第四天 | 24. 两两交换链表中的节点 19.删除链表的倒数第N个节点 面试题
    question1:SwapNodesinPairshttps://leetcode.cn/problems/swap-nodes-in-pairs/IwasalittleconfusedatfirstbecauseI'mthinkingwhethershouldIcreatanewhead,butsoonIcameupwiththeideaofcreatpre=Noneandwithan'if-els......
  • 206.反转链表
    1.题目介绍2.题解2.1迭代假设链表为1→2→3→∅,我们想要把它改成∅←1←2←3。在遍历链表时,将当前节点的next指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。作者:力扣......