每日一题——判断一个链表是否为回文结构

文章介绍了两种判断链表是否为回文结构的算法:一种是将链表元素存入数组并比较正反序,另一种是使用快慢指针找到链表中间点,反转后半部分并与前半部分比较。

题目


给定一个链表,请判断该链表是否为回文结构。
回文是指该字符串正序逆序完全一致。
数据范围: 链表节点数 0≤n≤105 ,链表中每个节点的值满足 ∣val∣≤107

示例1

输入:
{1}
返回值:
true

示例2

输入:
{2,1}
返回值:
false
说明:
2->1

示例3

输入:
{1,2,2,1}
返回值:
true
说明:
1->2->2->1

思路1


因为需要判断是否为回文结构,所以要比较头尾的数据,而链表无法随机查询数据,所以可以先将链表存入一个数组中,然后比较正序和反序的节点元素。

解答代码1


/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 *	ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
#include <vector>
class Solution {
public:
    /**
     * @param head ListNode类 the head
     * @return bool布尔型
     */
    bool isPail(ListNode* head) {
        // write code here
        if (head == nullptr) {
            return false;
        }
        std::vector<int> tmp;
        auto p = head;
        //将链表元素取出一次放入数组
        while (p != nullptr) {
            tmp.push_back(p->val);
            p = p->next;
        }
        auto it = tmp.rbegin();
        while (it != tmp.rend()) {
            if (head->val != *it) {
                //正向遍历与反向遍历不相同,则不是回文结构
                return false;
            }
            head = head->next;
            it++;
        }
        return true;
    }
};

思路2


使用快慢指针,快指针的速度为慢指针的两倍,当快指针到达链表尾部时,慢指针到达中间位置,将慢指针之后的部分进行反转,再与前半部分进行比较。(需要注意链表个数是奇数和偶数的区别)

解答代码1


/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 *	ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
#include <vector>
class Solution {
public:
    /**
     * @param head ListNode类 the head
     * @return bool布尔型
     */
    bool isPail(ListNode* head) {
        // write code here
        if (head == nullptr) {
            return false;
        }
        auto fast = head;
        auto low = head;
        //通过快慢指针找到中点
        while (fast != nullptr && fast->next != nullptr) {
            fast = fast->next->next;
            low = low->next;
        }
        //如果fast不为空,说明链表的长度是奇数个
        if (fast != nullptr) {
            low = low->next;
        }
        //反转后半部分链表
        auto rev = reverse(low);
        while (rev != nullptr) {
            if (head->val != rev->val) {
                return false;
            }
            head = head->next;
            rev = rev->next;
        }
        return true;
    }

    ListNode* reverse(ListNode* head) {
        if (head == nullptr) {
            return nullptr;
        }

        ListNode* pre = nullptr;
        auto cur = head;
        while (cur != nullptr) {
            auto tmp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = tmp;
        }
        return pre;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值