234. Palindrome Linked List(链表模板)

Given a singly linked list, determine if it is a palindrome.

Follow up:

Could you do it in O(n) time and O(1) space?

思路1:遍历一边链表,把它放到数组或VECTOR里,转化为字符串的回文判断。

但是时间复杂度和空间复杂度都是O(n)。

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        vector<int> v;
        while(head){
            v.push_back(head->val);
            head=head->next;
        }
        for(int i=0,j=v.size()-1;i<j;i++,j--){
            if(v[i]!=v[j])
                return false;
        }
        return true;
    }
};

思路二:先找到链表的中间的那个点,把链表分割成2个部分。

这个方法可以用判断链表是否有环的思想,设置两个指针,

一个每次向前移动一步,一个每次移动二步。

然后将链表的一个部分反转,再依次进行比较。

/**
 * 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,*t2=head;
       while(t2&&t2->next){
            t1=t1->next;
            t2=t2->next->next;
       }
       if(t2){
          t1=t1->next;
       }
       t1=reverseList(t1);
       while(t1){
           if(t1->val!=head->val)
                return false;
            t1=t1->next;
            head=head->next;
       }
       return true;
    }
    ListNode* reverseList(ListNode* head){
        if(!head||!head->next)return head;
        ListNode *t1=head,*t2=head->next;
        t1->next=NULL;
        while(t2){
            ListNode *t3=t2->next;
            t2->next=t1;
            t1=t2;
            t2=t3;
        }
        return t1;//错误点,return head;
    }
};
这个题目自己在写反转链表的时候,return的返回值写成了head让我花了好久才找出来了这个BUG。

还写了链表的测试代码。保留下,方便以后调试代码吧。

#include <iostream>
#include<cstring>
#include <vector>
#include <cstdio>
#include <assert.h>
using namespace std;
struct ListNode
{
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(NULL) {}
};
 ListNode *creatList(int n) {
        ListNode head(-1);
        ListNode *prev = &head;
        int val;
        for (int i = 0; i < n; ++i) {
            cin >> val ;
            prev->next = new ListNode(val);
            prev = prev->next;
        }
        prev->next = NULL;
        return head.next;
}
void printList(ListNode*pHead){
    if(!pHead)return;
    while(pHead){
        cout<<pHead->val<<" ";
        pHead=pHead->next;
    }
    cout<<endl;
}
    ListNode* reverseList(ListNode* head){
        if(!head||!head->next)return head;
        ListNode *t1=head,*t2=head->next;
        t1->next=NULL;
        while(t2){
            ListNode *t3=t2->next;
            t2->next=t1;
            t1=t2;
            t2=t3;
        }
        return head;
    }

 bool isPalindrome(ListNode* head) {
       if(!head||!head->next){
           return true;
       }
       ListNode *t1=head,*t2=head;
       while(t2&&t2->next){
            t1=t1->next;
            t2=t2->next->next;
       }
       if(t2){
          t1=t1->next;
       }
       t1=reverseList(t1);
       while(t1){
           if(t1->val!=head->val)
                return false;
            t1=t1->next;
            head=head->next;
       }
       return true;
    }

void destoryList(ListNode* pHead)
{
    assert(pHead!=NULL);
    ListNode* pNext = pHead->next;
    while(pNext != NULL)
    {
        delete pHead;
        pHead = pNext;
        pNext = pHead->next;
    }
    delete pHead;
    pHead = NULL;
    return;
}
int main()
{
    ListNode* head = creatList(4);

    printf("%d\n",isPalindrome(head));

    destoryList(head);
}



pta链表重排(Palindrome Linked List),也称为回文链表,是指链表中的节点按奇数位置到偶数位置,或反过来都能形成回文串。在C++中,实现这个功能的一个常见方法是通过迭代或递归的方式遍历链表,并分别保存两个指针,一个向前移动,一个向后移动,同时交换它们所指向节点的数据。 以下是简单的C++代码示例,展示了如何判断一个单链表是否是回文,以及如何将其转换为回文: ```cpp #include <iostream> using namespace std; struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; // 判断链表是否为回文 bool isPalindrome(ListNode* head) { if (head == nullptr || head->next == nullptr) return true; // 空链表或只有一个元素都是回文 ListNode *slow = head, *fast = head->next; while (fast && fast->next) { if (slow->val != fast->val) return false; slow = slow->next; fast = fast->next->next; } return true; } // 将链表转换为回文 ListNode* palindromize(ListNode* head) { if (isPalindrome(head)) return head; ListNode dummy(0); // 创建虚拟头结点 dummy.next = head; ListNode *prev = &dummy, *cur = head, *rev = nullptr; while (cur) { ListNode *nextTemp = cur->next; cur->next = rev; if (rev) rev->prev = cur; rev = cur; cur = nextTemp; prev = prev->next; } prev->next = dummy.next; dummy.next->prev = &dummy; return dummy.next; } void printList(ListNode* head) { ListNode* temp = head; while (temp) { cout << temp->val << " -> "; temp = temp->next; } cout << "nullptr" << endl; } int main() { // 创建一个非回文链表并测试 ListNode* list = new ListNode(1); list->next = new ListNode(2); list->next->next = new ListNode(3); list->next->next->next = new ListNode(4); list->next->next->next->next = new ListNode(5); cout << "Original List: "; printList(list); // 转换为回文 list = palindromize(list); cout << "Palindrome List: "; printList(list); return 0; } ``` 在这个例子中,`palindromize`函数首先检查链表是否已经是回文,如果不是,则创建一个新的回文结构。然后,通过反转链表的一半并与原链表拼接,实现了链表的回文化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值