目录
链接:
链表的回文结构_牛客题霸_牛客网 (nowcoder.com)
可分为3个步骤
<1>:寻找中间节点,若为奇数,返回中间值,若为偶数,返回中间的第二个节点
<2>:将中间节点后面部分,进行倒叙(即反转链表)
<3>:(在中间节点为空前)判断起始位置,于中间节点位置,到末尾是否相同
1.寻找中间节点
链接:力扣https://leetcode.cn/problems/middle-of-the-linked-list/
<1>:两次遍历
第一次遍历,记录链表中的元素个数,第二次遍历返回所求节点。
代码为:
struct ListNode* middleNode(struct ListNode* head)
{
int size = 0;
struct ListNode* cur = head;
while(cur)
{
++size;
cur = cur->next;
}
int k = 0;
cur = head;
//当 k = size/2 时,为要返回的节点
while(k < size/2)
{
//链表从0开始数
++k;
cur = cur->next;
}
return cur;
}
<2>:快慢指针
slow 走一步,fast 走两步,
总个数为奇数时,当 fast 走到最后一个位置,slow 刚好位于中间位置
若为偶数时,当 fast 走到 fast->next == NULL 时, slow 刚好位于第二个中间节点
代码为:
struct ListNode
{
int val;
struct ListNode *next;
};
struct ListNode* middleNode(struct ListNode* head)
{
//快慢指针
//slow 走一步,fast 走两步,总个数为奇数时,当 fast 走到最后一个位置,slow 刚好位于中间位置
//若为偶数时,当 fast 走到 fast->next == NULL 时, slow 刚好位于第二个中间节点
struct ListNode* slow = head;
struct ListNode* fast = head;
//若 fast 为空, fast->next 就无法访问,要先判断 fast
// && 两个同时为真,一个为假即为假
//此处不使用 || ,fast 于fast->next 存在关系
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
2.反转链表
链接:
力扣https://leetcode.cn/problems/reverse-linked-list/
<1>:指针解法
代码为:
struct ListNode* reverseList(struct ListNode* head)
{
//链表为空
if(head == NULL)
{
return NULL;
}
struct ListNode* n1 = NULL;
struct ListNode* n2 = head;
struct ListNode* n3 = n2->next;
while(n2)
{
n2->next = n1;
n1 = n2;
n2 = n3;
if(n3)
{
n3 = n3->next;
}
}
return n1;
}
<2>:头插解法
代码为:
struct ListNode* reverseList(struct ListNode* head)
{
//头插
struct ListNode* rhead = NULL;
struct ListNode* cur = head;
while(cur)
{
struct ListNode*next = cur->next;
cur->next = rhead;
rhead = cur;
cur = next;
}
return rhead;
}
3.判断是否为回文结构
一 一对比链表中元素的值是否相同,若相同返回 true,若不相同返回false。
代码为:
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* removeElements(struct ListNode* head)
{
//将上述所得的 slow 进行逆置,1->2->3 3-2->1
struct ListNode* cur = head;
struct ListNode* rhead = NULL;
while(cur)
{
//头插
struct ListNode* next = cur->next;
cur->next = rhead;
rhead = cur;
cur = next;
}
return rhead;
}
class PalindromeList
{
public:
bool chkPalindrome(ListNode* A)
{
struct ListNode* mid = FindMid(A);
struct ListNode* rmid = removeElements(mid);
while(rmid)
{
if(A->val == rmid->val)
{
A = A->next;
rmid = rmid->next;
}
else
{
return false;
}
}
return true;
}
};