回文链表

来源:互联网 发布:数据库优化方案 编辑:程序博客网 时间:2024/05/22 03:07
    回文链表其实也是链表反转的变形;也可以用栈实现。

//对于一个链表,请设计一个时间复杂度为O(n), 额外空间复杂度为O(1)的算法,判断其是否为回文结构。//给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。//测试样例://1->2->2->1//返回:true#include <stdio.h>#include <iostream>using namespace  std;struct ListNode {    int val;    struct ListNode *next;    ListNode(int x) : val(x), next(nullptr) {}};//思路1:空间O(n) 整个链表遍历两边, 开一个栈,第一遍遍历把链表中每个元素push进栈中,这样堆中的元素的pop顺序就是链表的倒序输出;第二遍就开始pop栈中数据,每pop一个数据,就把这个数据跟链表中进行对比,如果相同继续往下走,如果不同返回false。////思路2:空间O(1),使用快慢指针法,第一步设置一个块指针和一个慢指针,快指针一次走两步,慢指针一次走一步(慢),当快指针下一步为null的时候说明慢指针已经走了一半,这就可以找到中间节点。第二步反转中间链表后面的指针,第三部从头尾向中间扫描,对比每个元素是否相等,如果都相等,则是回文数,否则不是回文数。(下面网友易水给出了代码实现,这里不再叙述)class PalindromeList {public:    bool chkPalindrome(ListNode* A) {        // write code here            ListNode* pSlow = A;        ListNode* pQucik = A;        //快慢指针找到中间节点        while (pQucik!=nullptr&&pQucik->next!=nullptr)        {            pQucik = pQucik->next->next;            pSlow = pSlow->next;                    }        //将中点结点后的指针反转        ListNode* pNode = nullptr;        pNode = pSlow->next;        ListNode* pHead = pSlow;  //反转链表的头        while (pNode!=nullptr)   //测试未通过        {            ListNode* temp = pNode;            pNode = pNode->next;            temp->next = pHead;            pHead = temp;        }        while (A!=pHead)        {            if (A->val!=pHead->val)            {                return false;            }            A = A->next;            pHead = pHead->next;        }        return true;    }};class PalindromeList1 {public:    bool chkPalindrome(ListNode* A) {  //A不带头节点        // write code here        if (A == nullptr || A->next == nullptr)            return true;        ListNode* head = nullptr;        ListNode* node = A;    /*    //将中间节点后的指针反转                ListNode* p = slow->next;        ListNode* p1 = p->next;        while (p != NULL){            p->next = slow;            slow = p;            p = p1;            p1 = p1->next;        }*/        while (node != nullptr){            ListNode* temp = node;            node = node->next;            temp->next = head;            head = temp;        }        while (A != nullptr&&head != nullptr){            if (A->val != head->val){                return false;            }            A = A->next;            head = head->next;        }        return true;    }};void print(ListNode* pHead){    if (pHead==nullptr)    {        puts("链表为空!");        return;    }    puts("链表为:");    ListNode*pNode = pHead->next;    while (pNode)    {        printf("%d ->", pNode->val);        pNode = pNode->next;    }    cout << "NULL\n";}ListNode* create(){    ListNode* pHead, *pNode, *temp;    int x;    pHead = pNode = (ListNode*)malloc(sizeof(ListNode));  //带头节点的链表    printf("请输入链表数据,以0为结束标志:\n");    scanf("%d", &x);    while (x)    {        temp = (ListNode*)malloc(sizeof(ListNode));        temp->val = x;        pNode->next = temp;        pNode = temp;        scanf("%d", &x);    }    pNode->next = nullptr;    return pHead;}int main(){    ListNode *pHead = create();    print(pHead);    PalindromeList s;    bool val=s.chkPalindrome(pHead);    cout << val << endl;    return 0;}

 

0 0
原创粉丝点击