回文链表

本文探讨了如何判断一个链表是否为回文链表,提供了三种解法:使用头插法建立新链表、反转链表后半部分进行比较、使用栈实现反向比较。每种方法均有详细的代码实现。

请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false

示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

解题思路:
使用头插法建立新的链表,即新的节点永远排在头节点的后面,这样将原来的链表反向排列,然后遍历两个链表进行比较,每个节点都相同则返回True;否则,返回False。
这个解法的空间复杂度和时间复杂度都为O(n),在提交记录中排在后面,不是最好的,暂做为一种解法。

Python:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        #使用头插法建立新链表
        
        first = ListNode(None) #头节点
        p = head
        while( p ):
            new = ListNode(p.val)
            new.next = first.next
            first.next = new
            p = p.next
        p = head
        while( p ):
            if ( first.next.val != p.val):
                return False
            first = first.next
            p = p.next
        return True

C++
方法一:
使用头插法创建新的单链表,不满足O(1)的空间复杂度。

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(!head || !head->next) 
            return true;
        ListNode * newlist = new ListNode(-1);   //新链表头节点,头插法创建新链表
        ListNode *p1 = head, *p2 ;        
        while(p1){
            p2 = new ListNode(p1->val);
            p2->next = newlist->next;
            newlist->next = p2;
            p1 = p1->next;  
        }
        while(head){
            if(head->val != newlist->next->val)
                return false;
            head = head->next;
            newlist = newlist->next;
        }
        return true;
    }
};

方法二:
反转链表的后半部分再进行比较。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(!head || !head->next) 
            return true;
        ListNode* slow = head, *fast = head, *temp = nullptr;
        //找中点
        while(fast->next && fast->next->next){
            slow = slow->next;
            fast = fast->next->next;
        }
        //反转链表后半部分
       ListNode * t1 = slow, *t2 = slow->next;
        while(t2){
            t1 = t2;
            t2 = t1->next;
            t1->next = temp;
            temp = t1;
        }
        slow->next = temp;
        //比较前半部分和后半部分
        while(slow->next){
            if(head->val != slow->next->val) return false;
            head = head->next;
            slow = slow->next;
        }
        return true;
    }
};

方法三:使用 栈 实现反向比较。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(!head || !head->next) 
            return true;
        ListNode *t1 = head;
        int count = 0;
        while(t1){
            ++count;
            t1 = t1->next;
        }
        t1 = head;
        int i = count / 2, r = count % 2;
        stack<int> sk1;
        for(; i != 0; --i){
            sk1.push(t1->val);
            t1 = t1->next;
        }
        t1 = r==0 ? t1 : t1->next;
        while(t1){
            if(sk1.top() != t1->val) return false;
            sk1.pop();
            t1 = t1->next;
        }
        return true;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值