题目描述:
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
测试样例:
1->2->2->1
返回:true
思路:
由于空间复杂度要求为O(1),也就是说临时占用空间和输入数据规模无关,因此无法利用数组或者是栈进行判断。因此先找到中间位置将后半部分指针翻转,然后两端分别比较。注意这种方法会修改原链表,但是空间复杂度要求为O(1)也只能这么做了。
程序运行流程:
1、利用快慢指针找到中间的位置(起初均指向头结点,然后pSlow一次走一步,pFast一次走两步。注意不需要区分链表结点个数是奇数还是偶数);
2、将后半部分指针翻转;
3、最后再进行一次遍历,一个从前向后,一个从后向前。
下图是演示图(分为链表结点个数奇数和偶数两种情况),当pFast或pFast->next到达尾部(为NULL)时,pSlow正好到达中间位置。其中当链表结点个数为偶数时,pFast首先变为NULL;当链表结点个数为奇数时,pFast->next首先变为NULL。
代码:
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 }
欢迎交流。