leetcode:234.回文链表(详解)

前言:内容包括-题目,代码实现,大致思路,代码解读

题目:

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

示例 1:


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


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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/palindrome-linked-list
 

代码实现:

//找中间结点
 struct ListNode*FindMid(struct ListNode*head)
 {
    struct ListNode* slow = head;
	struct ListNode* fast = head;
	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;
	}
	return slow;

 }

//翻转后半段链表
 struct ListNode* reverse(struct ListNode*head)
 {
    struct ListNode* prev = NULL;
	struct ListNode* cur = head;
	while (cur)
	{
		struct ListNode* next = cur->next;
		cur->next = prev;
		prev = cur;
		cur = next;
		if (next)
		{
			next = next->next;
		}
	}
	return prev;
 }

bool isPalindrome(struct ListNode* head)
{

  struct ListNode* mid = FindMid(head);
	struct ListNode* rmid = reverse(mid);
	while (rmid)
	{
		if (head->val == rmid->val)
		{
			head = head->next;
			rmid = rmid->next;
		}
		else
		{
			return false;
		}
	}
	return true;
}

大致思路:

1 翻转后半段链表:

   a 找到中间结点

   b 翻转中间结点(包括中间结点在内)后面的所有结点

2 比较前半段链表和翻转后的后半段链表:

   a 若是前半段中的结点值==后半段中的结点值  继续走向下一对要比较的结点

   b 若是前半段中的结点值!=后半段中的结点值,表示该链表非回文链表

比如:原链表 1 2 2 1

          翻转后半段: 1 2 1 2

          前半段 1 2和后半段 1 2 完全相同,表示该链表是回文链表

代码解读:

part 1 找寻中间结点的函数 FindMid

 struct ListNode*FindMid(struct ListNode*head)
 {
    struct ListNode* slow = head;
	struct ListNode* fast = head;
	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;
	}
	return slow;

 }

快慢指针法:slow一次走一步,fast一次走两步

当fast为NULL(结点个数为偶数个)或者fast->next为NULL(结点个数为奇数个)时循环结束,slow就是中间结点。

偶数个结点的链表它的中间结点有两个,我们取较后的一个为最终正确的中间结点

part 2 翻转后半段链表

 struct ListNode* reverse(struct ListNode*head)
 {
    struct ListNode* prev = NULL;
	struct ListNode* cur = head;
	while (cur)
	{
		struct ListNode* next = cur->next;
		cur->next = prev;//改变结点next的指向
        //下面是迭代
		prev = cur;
		cur = next;
		if (next)//next若已经是NULL,则不执行下面这行代码,否则就是对NULL指针解引用
		{
			next = next->next;
		}
	}
	return prev;//prev就是翻转后的链表的头结点
 }

 part 3

bool isPalindrome(struct ListNode* head)
{

  struct ListNode* mid = FindMid(head);
	struct ListNode* rmid = reverse(mid);
	while (rmid)
	{
		if (head->val == rmid->val)
		{
			head = head->next;
			rmid = rmid->next;
		}
		else
		{
			return false;
		}
	}
	return true;
}

遍历比较前半段链表和翻转后的后半段链表

结点的值相同则继续比较下一对

结点的值不同则返回false

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值