力扣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)

相关推荐
aini_lovee2 小时前
多目标粒子群优化(MOPSO)双适应度函数MATLAB实现
人工智能·算法·matlab
yong99902 小时前
图像融合与拼接:完整MATLAB工具箱
算法·计算机视觉·matlab
春风不语5052 小时前
深入理解主成分分析(PCA)
算法
apollowing2 小时前
启发式算法WebApp实验室:从搜索策略到群体智能的能力进阶(二十二)
算法·启发式算法·web app
晚枫歌F2 小时前
最小堆定时器
数据结构·算法
Lumos_7772 小时前
Linux -- 线程
java·jvm·算法
七颗糖很甜3 小时前
“十五五”气象发展规划:聚焦五大核心任务
大数据·python·算法
科研前沿3 小时前
镜像视界浙江科技有限公司的关键技术突破有哪些?
大数据·人工智能·科技·算法·音视频·空间计算
嫩萝卜头儿3 小时前
2 - 复杂度收尾 + 链表经典OJ
数据结构·算法·链表·复杂度
星马梦缘3 小时前
算法设计与分析 作业二 答案与解析
算法·图论·dfs·bfs·floyd-warshall·bellman_ford·多源最短路