0
点赞
收藏
分享

微信扫一扫

Leetcode刷题日记(十五)

捌柒陆壹 2022-04-14 阅读 40

老台词:欢迎来到一晚一度的leetcode刷题日记时间。今天我们继续来讲讲我们学习算法的重要朋友--递归。递归的重要性上篇刷题日记已经提到不少了,这就不罗嗦了。今天我们来看看一道回文链表的题目,继续体会递归的妙用。(好像前几期有讲到回文字符串)。

直接上题目:

第一种解题方法(双指针方法):

步骤:

  1. 复制链表值到数组列表中。
  2. 使用双指针法来比较两端的元素,并向中间移动。一个指针从起点向中间移动,另一个指针从终点向中间移动

解题代码:

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);
    }
};

第三种解题方法(快慢指针):慢指针一次走一步,快指针一次走两步:

步骤:

  1. 找到前半部分链表的尾节点。
  2. 反转后半部分链表。
  3. 判断是否回文。
  4. 恢复链表。
  5. 返回结果

 解题代码(比较长,扩展一下知识面也是挺不错的):

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;
    }
};

好啦,今天的分享就到此结束啦,早点睡觉,少熬夜。

本贴为博主亲手整理。如有错误,请评论区指出,一起进步。谢谢大家的浏览.

举报

相关推荐

0 条评论