老台词:欢迎来到一晚一度的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;
     }
 };
好啦,今天的分享就到此结束啦,早点睡觉,少熬夜。
本贴为博主亲手整理。如有错误,请评论区指出,一起进步。谢谢大家的浏览.










