老台词:欢迎来到一晚一度的leetcode刷题日记时间。今天我们继续来讲讲我们学习算法的重要朋友--递归。递归的重要性上篇刷题日记已经提到不少了,这就不罗嗦了。今天我们来看看一道回文链表的题目,继续体会递归的妙用。(好像前几期有讲到回文字符串)。
直接上题目:
第一种解题方法(双指针方法):
步骤:
- 复制链表值到数组列表中。
- 使用双指针法来比较两端的元素,并向中间移动。一个指针从起点向中间移动,另一个指针从终点向中间移动
解题代码:
class Solution {
public:
bool isPalindrome(ListNode* head)//传入链表的头指针地址
{
vector<int> vals;//定义动态数组类型的vals
while (head != nullptr)
{
vals.emplace_back(head->val);//emplace_back和push_back其实是一样的,这里意思是把头指针指向结点的数据都传进入动态数组vals中
head = head->next;//头指针依次向后移动
}
for (int i = 0, j = (int)vals.size() - 1; i < j; ++i, --j)//定义两个指针
{
if (vals[i] != vals[j])
{
return false;
}
}
return true;
}
};
第二种解题方法(递归方法):
解题代码:
class Solution {
ListNode* frontPointer;//定义一个头指针
public:
bool recursivelyCheck(ListNode* currentNode)// currentNode指针是从后到头
{
if (currentNode != nullptr)
{
if (!recursivelyCheck(currentNode->next))//采用递归
{
return false;
}
if (currentNode->val != frontPointer->val) {
return false;
}
frontPointer = frontPointer->next;//指针依次向后移动
}
return true;
}
bool isPalindrome(ListNode* head)
{
frontPointer = head;
return recursivelyCheck(head);
}
};
第三种解题方法(快慢指针):慢指针一次走一步,快指针一次走两步:
步骤:
- 找到前半部分链表的尾节点。
- 反转后半部分链表。
- 判断是否回文。
- 恢复链表。
- 返回结果
解题代码(比较长,扩展一下知识面也是挺不错的):
class Solution {
public:
bool isPalindrome(ListNode* head) {
if (head == nullptr) {
return true;
}
// 找到前半部分链表的尾节点并反转后半部分链表
ListNode* firstHalfEnd = endOfFirstHalf(head);//找到前半部分链表的尾节点
ListNode* secondHalfStart = reverseList(firstHalfEnd->next);//反转后半部分链表
// 判断是否回文
ListNode* p1 = head;
ListNode* p2 = secondHalfStart;
bool result = true;
while (result && p2 != nullptr) {
if (p1->val != p2->val) {
result = false;
}
p1 = p1->next;
p2 = p2->next;
}
// 还原链表并返回结果
firstHalfEnd->next = reverseList(secondHalfStart);
return result;
}
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr != nullptr) {
ListNode* nextTemp = curr->next;
curr->next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
ListNode* endOfFirstHalf(ListNode* head) {
ListNode* fast = head;
ListNode* slow = head;
while (fast->next != nullptr && fast->next->next != nullptr) {
fast = fast->next->next;//快指针走两步
slow = slow->next;//慢指针走一步
}
return slow;
}
};
好啦,今天的分享就到此结束啦,早点睡觉,少熬夜。
本贴为博主亲手整理。如有错误,请评论区指出,一起进步。谢谢大家的浏览.