力扣Hot100——234.回文链表

234.回文链表

解题思路

回文链表的话,就是第一个数和倒数第一个数相同,第二个数和倒数第二个数相同,一次类推,但是链表我们无法直接从最后一个节点开始从后往前推,因此对于判断是不是回文链表,首先我们需要找到链表的中间节点

1. 链表的中间节点

对于长度为奇数 的链表,正中间的节点就是中间节点。

对于长度为偶数 的链表,找正中间右边的节点。

举例如下:

对于链表

1->2->3->4->5

中间节点就是正中间的3。

对于链表

1->2->3->4->5->6

中间节点是正中间右边的4。

2.反转链表

随后对得到了中间节点之后的链表部分进行反转链表,也就是说:

奇数链表:

3->4->5反转为3<-4<-5,而另一边1->2->3

偶数链表

1->2->3->4,而另一边4<-5<-6。

3.回文链表判断

我们记反转后的头节点是head2。

同时得注意得到了反转之后的链表之后,进行回文判断的时候,判断条件当中应该是head2是否为空,如果判断条件当中是head的话,那么对于奇数情况,head要比head2多走一步,但这时候head2已经是空的了,就会出现问题(head2.val,空指针异常)。

如何得到链表的中间节点呢?

使用快慢指针法,让快慢指针同时指向head,快指针每次移动2步,慢指针每次移动1步,当快指针为null或者快指针的next为null时,此时满指针的所指就是中间节点。

代码

C++

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    //找到中间节点
    ListNode* Getmidddle(ListNode* head)
    {
        ListNode* fast = head;
        ListNode* slow = head;
        while(fast && fast->next)
        {
            slow = slow->next;
            fast = fast->next->next;
        } 
        return slow;
    }

    //反转中间节点之后的链表部分
    ListNode* ReverseLink(ListNode* head)
    {
        ListNode* pre = NULL;
        ListNode* cur = head;
        ListNode* nxt = NULL;
        while(cur)
        {
            nxt = cur->next;
            cur->next = pre;
            pre = cur;
            cur = nxt;
        }
        return pre;
    }
    bool isPalindrome(ListNode* head) {
        //得到中间节点
        ListNode* middle = Getmidddle(head);
        ListNode* head2 = ReverseLink(middle);
        while(head2)
        {
            if(head->val != head2->val)
                return false;
            head = head->next;
            head2 = head2->next;
        }
        return true;
    }
};

python

python 复制代码
# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):

    # 找到中间结果,对于奇数,直接就是中间
    # 对于偶数,则是中间的右边节点
    def GetMiddleNode(self, head):
        """
        :type head: Optional[ListNode]
        :rtype: ListNode
        """
        slow, fast = head, head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
        return slow

    # 反转链表
    # 反转从中间节点到原本链表之间的关系,比如1->2->3->4->5->6
    # 反转后:1->2->3->4<-5<-6
    def reverseLink(self, head):
        """
        :type head: Optional[ListNode]
        :rtype: ListNode
        """
        pre, cur= None, head
        while cur:
            nxt = cur.next
            cur.next = pre
            pre = cur
            cur = nxt
        return pre
        

    def isPalindrome(self, head):
        """
        :type head: Optional[ListNode]
        :rtype: bool
        """
        #1. 找到中间节点
        middle = self.GetMiddleNode(head)
        #2. 反转链表
        head2 = self.reverseLink(middle)
        while head2:
            if head.val == head2.val:
                head = head.next
                head2 = head2.next
            else:
                return False
        return True
            


        

参考

O(1) 空间做法:寻找中间节点+反转链表(Python/Java/C++/C/Go/JS/Rust)

相关推荐
心中有国也有家7 小时前
cann-recipes-infer:昇腾 NPU 推理的“菜谱集合”
经验分享·笔记·学习·算法
绝知此事8 小时前
【算法突围 01】线性结构与哈希表:后端开发的收纳术
java·数据结构·算法·面试·jdk·散列表
碧海银沙音频科技研究院8 小时前
通话AEC与语音识别AEC的软硬回采链路
深度学习·算法·语音识别
csdn_aspnet8 小时前
Python 算法快闪 LeetCode 编号 70 - 爬楼梯
python·算法·leetcode·职场和发展
m0_6294947311 小时前
LeetCode 热题 100-----26.环形链表 II
数据结构·算法·leetcode·链表
壹号用户11 小时前
用队列实现栈
数据结构·算法
做人求其滴12 小时前
面试经典 150 题 380 274
c++·算法·面试·职场和发展·力扣
daad77712 小时前
记一组无人机IMU传感器数据
算法
计算机安禾12 小时前
【c++面向对象编程】第42篇:模板特化与偏特化:为特定类型定制实现
开发语言·c++·算法