回文链表(C语言)

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

示例1:
输入:head = [1,2,2,1]
输出:true

示例2:
输入:head = [1,2]
输出:false

注:链表中节点数目在范围[1, 10^5] 内

题目来源(力扣):回文链表

【基本思路】
先找到中间节点,借此将链表拆分为两部分,并对后半部分进行反转。
再同时遍历前半和后半部分的链表,判断相对应的两个节点的值是否相等。如果存在不相等,则该单链表一定不是回文链表。

【代码实现】

typedef struct ListNode ListNode;

//反转链表函数
ListNode* reverseList(ListNode* head){
	ListNode* cur = head;
	ListNode* newhead = NULL;
	while (cur)
	{
		ListNode* next = cur->next; 
		cur->next = newhead;
		newhead = cur;
		cur = next;
	}
	
	return newhead;
}

bool isPalindrome(struct ListNode* head){
    //用快慢指针法寻找中间节点
    ListNode* slow = head;
    ListNode* fast = head;
    ListNode* prev = head;  // prev是定位链表中间节点的前一个节点
    while (fast && fast->next)
    {
        prev = slow;
        slow = slow->next;
        fast = fast->next->next;
    }

    prev->next = NULL;  // 一定要对前半部分链表的末尾置空
    slow = reverseList(slow);  // 反转后半部分的链表
	
	//同时遍历前半和后半部分的链表
    while (head)
    {
    	//判断相对应的两个节点的值是否相等
        if (head->val != slow->val)  // 如果存在不相等,则该单链表一定不是回文链表
        {
            return false;
        }

        head = head->next;
        slow = slow->next;
    }

	//能走到这里,说明该单链表必是回文链表
    return true;
}

因为此解法需拆分原链表,故最后需将链表复原为原来的样子(再加上部分代码即可)。

想详细了解上面的两个子步骤的,请点击下面两个博客链接:
链表的中间结点
反转链表

本专栏
有关链表的题目

其它专栏
有关数组的题目

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值