给定一个链表,怎么判断链表中存储的数据是回文

来源:互联网 发布:百度申诉 网络异常 编辑:程序博客网 时间:2024/06/09 18:10

check whether a single linked list is palindrome. for example: 1->2->1,return ture. and 1->2->3->1 return false; and can you resolve it in linear time. 如果是数组那用递归和非递归都很好解决了,但是链表貌似有点麻烦。

首先给出思路就是:先找到链表中间的节点,记得区分链表中节点个数是奇数还是偶数。然后把链表的前一半节点放入栈之中,之后从中间节点的后一个节点开始,此节点和栈顶节点所存储的值进行比较,如果相等则继续进行后续比较,直到链表结尾。如果中间出现不相等的情况,则不是回文。 那么,怎么样找到链表的中间节点呢。一个方法是遍历一遍链表,统计它的节点个数,然后取个数的中间值(记得区奇数偶数)。这样再次遍历就会找到中间的节点。说道这里应该有思路了,但是还有一个更好的解法,就是设定双指针。

#include<iostream>#include<stack>using namespace std;typedef struct node{int data;struct node *next;}LinkNode, *LinkList;void create_list(LinkList *L, int *a, int n) {int i = 0;LinkNode *p = NULL;LinkNode *temp = NULL;while(i < n) {p = (LinkNode*)malloc(sizeof(LinkNode));p->data = a[i];p->next = NULL;if(*L == NULL) {*L = p;} else {temp->next = p;}temp = p;i++;}}int is_palindrome(LinkList head) {int length = 0;int mid = 0;int i;stack<LinkNode*> m_stack;LinkNode *p = head;LinkNode *temp = NULL;int flag = 1;while(p) {length++;p = p->next;}if(length %2 == 0) {mid = length / 2;} else {mid = length / 2 + 1;}p = head;i = 1;while(i <= mid - 1) {m_stack.push(p);p = p->next;i++;}if(length % 2 == 0) {m_stack.push(p);}p = p->next;while(!m_stack.empty() && p) {temp = m_stack.top();m_stack.pop();if(temp->data != p->data) {flag = 0;break;}p = p->next;}return flag;}void main() {int a[] = {1, 2, 3, 4, 5, 4, 3, 2, 1};int n = sizeof(a) / sizeof(int);LinkList head = NULL;create_list(&head, a, n);if(is_palindrome(head)) {cout << "yes" << endl;} else {cout << "no" << endl;}getchar();}

双指针的解法:

bool isPanli(LinkList head){stack<LinkNode*> stk;LinkNode* slow = head;LinkNode* fast = head;bool flag = false;while (fast) {stk.push(slow);slow = slow->next;fast = fast->next;if (fast) {fast = fast->next;} elseflag = true;}if (flag)stk.pop();while (!stk.empty()) {if (stk.top()->data == slow->data){stk.pop();slow = slow->next;}elsereturn false;}return true;}


原创粉丝点击