leetcode234:回文链表

题目链接

leetcode

题目描述

给你一个单链表的头节点 head ,判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false

C++ 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <iostream>
#include <vector>
using namespace std;

// 链表结点的定义
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};

// 辅助函数:创建链表
ListNode* createList(const vector<int>& nums) {
ListNode* dummy = new ListNode(-1);
ListNode* cur = dummy;
for (int num : nums) {
cur->next = new ListNode(num);
cur = cur->next;
}
return dummy->next;
}

// 辅助函数:打印链表
void printList(ListNode* head) {
while (head != nullptr) {
cout << head->val << " ";
if (head->next != nullptr) cout << "-> ";
head = head->next;
}
cout << endl;
}

// 辅助函数:释放链表内存
void deleteList(ListNode* head) {
while (head != nullptr) {
ListNode* temp = head;
head = head->next;
delete temp;
}
}

/*
递归实现

时间复杂度:O(n)
其中 n 指的是链表的长度。
空间复杂度:O(n)
递归的空间复杂度,考虑堆栈的使用情况。
*/
class Solution_0 {
public:
bool isPalindrome(ListNode* head) {
frontHead = head;
return checkPalindrome(head);
}

bool checkPalindrome(ListNode* node) {
if (node != nullptr) {
if (!checkPalindrome(node->next)) {
return false;
}
if (node->val != frontHead->val) {
return false;
}
frontHead = frontHead->next;
}

return true;
}

private:
ListNode* frontHead;
};

/*
迭代实现,快慢指针

找到链表中前半部分的尾结点
反转链表的后半部分
判断该链表是否回文
还原链表
返回结果

时间复杂度:O(n)
其中 n 是链表的长度。
空间复杂度:O(1)
只修改原链表中结点的指向,在堆栈上的帧不超过 O(1)。
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return true;
}

// 找到链表中前半部分的尾结点
ListNode *slow = head, *fast = head;
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}

// 反转链表的后半部分
slow->next = reverseList(slow->next);

// 判断该链表是否回文
slow = slow->next, fast = head;
while (slow != nullptr) {
if (slow->val != fast->val) {
return false;
}
slow = slow->next;
fast = fast->next;
}

// 还原链表
fast->next = reverseList(fast->next);

return true;
}

ListNode* reverseList(ListNode* node) {
ListNode *prev = nullptr, *cur = node;

while (cur != nullptr) {
ListNode* temp = cur->next;
cur->next = prev;
prev = cur;
cur = temp;
}

return prev;
}
};

int main() {
Solution solution;
vector<vector<int>> head_cases = {
{1,2,2,1},
{1,2},
};

for (size_t i = 0; i < head_cases.size(); i++) {
// 创建链表
ListNode* head = createList(head_cases[i]);
cout << "Input: ";
printList(head);

// 判断是否为回文链表
bool result = solution.isPalindrome(head);
cout << "Output: " << (result ? "true" : "false") << endl;

// 释放内存
deleteList(head);
}

return 0;
}

leetcode234:回文链表
https://lcf163.github.io/2024/04/28/leetcode234:回文链表/
作者
乘风的小站
发布于
2024年4月28日
许可协议