前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >链表回文判断(C++)

链表回文判断(C++)

作者头像
xiaoxi666
发布2018-10-29 17:32:48
9680
发布2018-10-29 17:32:48
举报
文章被收录于专栏:xiaoxi666的专栏
代码语言:javascript
复制

题目描述:

代码语言:javascript
复制
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
代码语言:javascript
复制
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
代码语言:javascript
复制
测试样例:
代码语言:javascript
复制
1->2->2->1

返回:true
代码语言:javascript
复制
思路:  
  由于空间复杂度要求为O(1),也就是说临时占用空间和输入数据规模无关,因此无法利用数组或者是栈进行判断。因此先找到中间位置将后半部分指针翻转,然后两端分别比较。注意这种方法会修改原链表,但是空间复杂度要求为O(1)也只能这么做了。

程序运行流程:
  1、利用快慢指针找到中间的位置(起初均指向头结点,然后pSlow一次走一步,pFast一次走两步。注意不需要区分链表结点个数是奇数还是偶数);
代码语言:javascript
复制
  2、将后半部分指针翻转;
  3、最后再进行一次遍历,一个从前向后,一个从后向前。

下图是演示图(分为链表结点个数奇数和偶数两种情况),当pFast或pFast->next到达尾部(为NULL)时,pSlow正好到达中间位置。其中当链表结点个数为偶数时,pFast首先变为NULL;当链表结点个数为奇数时,pFast->next首先变为NULL。

代码:

代码语言:javascript
复制
  1 /*
  2 本程序说明:
  3 
  4 时间限制:3秒 空间限制:32768K 热度指数:8332
  5 本题知识点: 链表 栈
  6 
  7 题目描述
  8 对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
  9 给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
 10 测试样例:
 11 1->2->2->1
 12 返回:true
 13 
 14 */
 15 
 16 #include <iostream>
 17 using namespace std;
 18 
 19 struct ListNode {
 20     int val;
 21     struct ListNode *next;
 22     ListNode(int x) : val(x), next(NULL) {}
 23 };
 24 
 25 //链表结点构造
 26 ListNode*  create_list_node(int val)
 27 {
 28     ListNode* pNode = new ListNode(val);
 29     return pNode;
 30 }
 31 //链表结点连接
 32 void connect_list_node(ListNode* pCur, ListNode* pNext)
 33 {
 34     pCur->next = pNext;
 35 }
 36 
 37 
 38 
 39 class PalindromeList {
 40 public:
 41     bool chkPalindrome(ListNode* A) {
 42         // write code here
 43         ListNode* pSlow = A;
 44         ListNode* pFast = A;
 45 
 46         while(pFast != NULL && pFast->next != NULL)
 47         {
 48             pSlow = pSlow->next;
 49             pFast = pFast->next->next;
 50         }
 51         //反转链表后半部分指针
 52         ListNode* prev = pSlow;//临时保存用
 53         pSlow = pSlow->next;
 54         prev->next = NULL;//最中间的点的next置为NULL
 55         while(pSlow != NULL)
 56         {
 57             cout<<pSlow->val<<endl;
 58             ListNode* tmp = pSlow->next;//保存后面的结点
 59             pSlow->next=prev;
 60             prev = pSlow;
 61             pSlow = tmp;
 62         }
 63 
 64         ListNode* pForward = A;//指向头结点
 65         ListNode* pBackward= prev;//指向链表最后一个结点
 66 
 67         while(!(pForward == pBackward || pForward->next == pBackward))
 68         {
 69             if(pForward->val != pBackward->val)
 70                 return false;
 71             pForward = pForward->next;
 72             pBackward = pBackward->next;
 73         }
 74         return true;
 75     }
 76 };
 77 
 78 void test()
 79 {
 80     //创建结点
 81     ListNode* pNode1 = create_list_node(1);
 82     ListNode* pNode2 = create_list_node(1);
 83     ListNode* pNode3 = create_list_node(7);
 84     ListNode* pNode4 = create_list_node(2);
 85     ListNode* pNode5 = create_list_node(7);
 86     ListNode* pNode6 = create_list_node(1);
 87     ListNode* pNode7 = create_list_node(1);
 88 //    ListNode* pNode8 = create_list_node(45);
 89 //    ListNode* pNode9 = create_list_node(-7);
 90 
 91     //连接结点
 92     connect_list_node(pNode1,pNode2);
 93     connect_list_node(pNode2,pNode3);
 94     connect_list_node(pNode3,pNode4);
 95     connect_list_node(pNode4,pNode5);
 96     connect_list_node(pNode5,pNode6);
 97     connect_list_node(pNode6,pNode7);
 98 //    connect_list_node(pNode7,pNode8);
 99 //    connect_list_node(pNode8,pNode9);
100 
101     PalindromeList test;
102 
103     bool flag=test.chkPalindrome(pNode1);
104     cout<<flag<<endl;
105 
106 }
107 
108 int main()
109 {
110     test();
111     return 0;
112 }
代码语言:javascript
复制
欢迎交流。
代码语言:javascript
复制
代码语言:javascript
复制
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-08-04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档