leetcode 234 判断是不是回文链表

聪明的我想到了利用栈先进后出的特性,求出链表的长度之后前一半入栈,后一半出栈的方法,虽然简单易懂,但是效率有点低,贴代码

/**
 * 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:
    bool isPalindrome(ListNode* head) 
    {
        if(!head->next)
        return true;
        stack<int> good;
        int i = 0;
        ListNode* nice = head;
        while(nice)
        {
            i++;
            nice = nice->next;
        }
        nice = head;
        int j;
        for(j = 0 ; j < i/2 ; j++)
        {
            good.push(nice->val);
            nice = nice->next;
        }
        if(i-2*j)
        nice = nice->next;
        for(; j > 0 ; j--)
        {
            if(!good.empty() && nice->val == good.top())
            {
                good.pop();
                if(nice->next)
                nice = nice->next;
            }
            else
            return false;

        }
        if(good.empty())
        return true;
        else
        return false;
    }
};

递归的方法相当巧妙,画画图对着代码应该能整明白,下面贴代码

/**
 * 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* front;
    bool nice(ListNode* node)
    {
        if(node)
        {
            if(!nice(node->next))
            return false;
            if(node->val !=front->val)
            return false;
            front = front->next;
        }
        return true;
    }
    bool isPalindrome(ListNode* head) 
    {
        front = head;  
        return nice(head);      
    }
};

最巧妙的是一旦递归中有一步返回false,就会触发连锁反应,false到尽头,虽然效率很差。

还有一种方法,通过快慢指针,找到节点的中间位置,然后通过反转链表的方法,将后部分翻转,并进行比较

添加一下该做法的代码,最具参考意义的是翻转链表的过程,其中用了虚头部来实现不断的翻转,贴代码

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode() : val(0), next(nullptr) {}
 7  *     ListNode(int x) : val(x), next(nullptr) {}
 8  *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 9  * };
10  */
11 class Solution {
12 public:
13     bool isPalindrome(ListNode* head) 
14     {
15         //边找中点边翻转
16         ListNode* fast = head;
17         ListNode* slow = head;
18         ListNode* tempNode = head;
19         ListNode* dummyHead = new ListNode();
20         while(fast && fast->next)
21         {
22             fast = fast->next->next;
23             slow = slow->next;
24             //反转
25             tempNode->next = dummyHead->next;
26             dummyHead->next = tempNode;
27             tempNode = slow;
28         }
29         //长度为奇数 
30         if(fast)
31         slow = slow->next;
32         //虚头的next指针指向反转后链表的头结点
33         ListNode* halfHead = dummyHead->next;
34         while(slow && halfHead)
35         {
36             if(slow->val != halfHead->val)
37             return false;
38             slow = slow->next;
39             halfHead = halfHead->next;
40         }
41         return true;     
42     }
43 };

 

posted @ 2021-03-13 20:42  zhaohhhh  阅读(80)  评论(0)    收藏  举报