算法学习15- 判断一个链表是否为回文结构

算法学习15- 判断一个链表是否为回文结构

判断一个链表是否为回文结构

【题目】

给定一个链表的头节点head,请判断该链表是否为回文结构。
例如:
1->2->1,返回true。
1->2->2->1,返回true。
15->6->15,返回true。
1->2->3,返回false。

进阶:

如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1)。

图解算法

在这里插入图片描述

找到链表中心,倒叙链表,和前部分去比较

思路算法

  • 1)先得到链表的中间节点;
  • 2)从中间节点的下一个节点开始,反转链表。
  • 3)从中间节点处,断开原链表。
  • 4)用两个指针分别向两个端点移动,同时进行比较,数据相同则继 续,数据不同则直接返回false。直到遍历完成,最后返回true。

代码实现<hard.h>

#include <iostream>
#include <stack>
using namespace std;

struct Node
{
    int value;
    Node *next;
};
//进阶算法
bool isPalindrome3(Node *head)
{
    if(NULL == head || NULL == head->next)
        return true;
    Node *n1(head),*n2(head);
    while(NULL != n2 && NULL != n2->next)
    {
        n1 = n1->next;    //找到中间节点
        n2 = n2->next->next;
    }
    n2 = n1->next;    //右半部分的第一个节点
    n1->next =NULL;
    Node *n3 = NULL;
    while(NULL != n2)    //反转右半部分链表
    {
        n3 = n2->next;
        n2->next = n1;
        n1 = n2;
        n2 = n3;
    }
    n3 = n1;    //记录最后一个节点
    n2 = head;    //记录头节点
    bool res = true;
    while(NULL != n1 && NULL != n2)
    {
        if(n1->value != n2->value)
        {
            res = false;
            break;
        }
        n1 = n1->next;
        n2 = n2->next;
    }
    n1 = n3->next;
    n3->next = NULL;
    while(NULL != n1)
    {
        n2 = n1->next;
        n1->next = n3;
        n3 = n1;
        n1 = n2;
    }
    return res;
}

void printLists(Node *head)
{
    while(NULL != head)
    {
        cout << head->value << " " ;
        head = head->next;
    }
    cout << endl;
}

代码实现<easy.h>

#include <iostream>
#include <stack>
using namespace std;

struct Node
{
    int value;
    Node *next;
};

bool isPalindrome1(Node *head)
{
    stack<Node> s;
    Node *cur = head;
    while(NULL != cur)
    {
        s.push(*cur);    //将链表节点全部压入栈中
        cur  = cur->next;
    }
    while(NULL != head)
    {
        if(head->value != s.top().value)
            return false;
        s.pop();
        head = head->next;
    }
    return true;
}

//使用栈的优化算法
bool isPalindrome2(Node *head)
{
    if(NULL == head || NULL == head->next)
        return true;
    Node *right = head->next;
    Node *cur = head;
    while(NULL != cur->next && NULL != cur->next->next)
    {
        right = right->next;
        cur = cur->next->next;
    }
    stack<Node> s;
    while(NULL != right)
    {
        s.push(*right);        //将链表的右半部分压入栈
        right = right->next;
    }
    while(!s.empty())
    {
        if(head->value != s.top().value)
            return false;
        s.pop();
        head = head->next;
    }
    return true;
}

主方法<main.cpp>


int main()
{
    Node *head1 = NULL;
    Node *head2 = NULL;
    Node *ptr = NULL;
    
    for(int i =1;i<6;i++)//构造链表
    {
        if(NULL == head1)
        {    
            head1 = new Node;
            head1->value = i;
            head1->next = NULL;
            ptr = head1;
            continue;
        }
        ptr->next = new Node;
        ptr = ptr->next;
        ptr->value = i;
        ptr->next = NULL;
    }
    printLists(head1);
    if(isPalindrome1(head1) && isPalindrome2(head1) && isPalindrome3(head1) )
        cout << "Head1 is a palindrome list!" << endl;
    else
        cout << "Head1 is not a palindrome list!" << endl;
    Node *right = NULL;
    Node *tmp = NULL;
    for(int i =1;i<5;i++)//构造回文结构的链表
    {
        if(NULL == head2 && NULL == right)
        {    
            head2 = new Node;
            head2->value = i;
            head2->next = NULL;
            ptr = head2;
            
            right = new Node;
            right->value = 5-i;
            right->next = NULL;
            tmp = right;
            continue;
        }
        ptr->next = new Node;
        ptr = ptr->next;
        ptr->value = i;
        ptr->next = NULL;
        
        tmp->next = new Node;
        tmp = tmp->next;
        tmp->value =5-i;
        tmp->next = NULL;
    }
    ptr->next = right;
    printLists(head2);
    if(isPalindrome1(head2) || isPalindrome2(head2) || isPalindrome3(head2) )
        cout << "Head2 is a palindrome list!" << endl;
    else
        cout << "Head2 is not a palindrome list!" << endl;

    return 0;
}
发布了27 篇原创文章 · 获赞 1 · 访问量 1033

猜你喜欢

转载自blog.csdn.net/qq_45205390/article/details/104139043
今日推荐