LeetCode题目
1. 返回链表的中间结点
LeetCode链接: 【链表的中间结点】
思路1: 最容易想到的思路是先统计整个链表的结点个数,然后就可以得出中间结点的位置是在第几个,最后再从头结点走到中间结点位置即可。
代码实现如下:
struct ListNode* middleNode(struct ListNode* head){
int count=0;
struct ListNode* cur=head;
//求链表中有多少结点
while(cur!=NULL)
{
count++;
cur=cur->next;
}
//求出中间节点的位置
count=count/2;
//找到中间结点
cur=head;
while(count--)
{
cur=cur->next;
}
return cur;
}
思路2: 采用快慢指针法,慢指针走一步,快指针走两步;当快指针的指针域为空指针或者快指针为空指针时就结束,此时慢指针就是中间结点。
过程分析如下:
代码实现如下:
struct ListNode* middleNode(struct ListNode* head){
struct ListNode* slow=head;
struct ListNode* fast=head;
//有两种情况快指针要停下
while(fast && fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
2. 输出该链表中倒数第k个结点
LeetCode链接: 【22. 链表中倒数第k个节点】
这道题也是采用两个指针来解决,先让快指针走k步,这样快指针和慢指针的距离就是k步; 然后快指针走一步,慢指针也走一步;当快指针走到空指针时,慢指针还是距离快指针k步;这样慢指针就是倒数第k个结点。
过程分析如下:
代码实现如下:
struct ListNode* getKthFromEnd(struct ListNode* head, int k){
struct ListNode* slow=head;
struct ListNode* fast=head;
//先让快指针走k步,这样快指针和慢指针的距离就是k步
while(k--)
{
//防止k过大,造成对空指针进行解引用
if(fast==NULL)
{
return NULL;
}
fast=fast->next;
}
//快指针走一步,慢指针也走一步
//当快指针走到空指针时,慢指针还是距离快指针k步
//这样慢指针就是倒数第k个结点
while(fast!=NULL)
{
slow=slow->next;
fast=fast->next;
}
return slow;
}
3. 链表的回文结构
LeetCode链接: 【回文链表】
我们可以观察到回文链表如果以中间结点为对称轴,那么两边的值是一样的;所以我们判断是不是回文链表,先找到中间结点,然后以中间结点为起点把右边的结点给反转过来,这样就可以对比左右两边的结点了,全部相同就是回文链表,如果有一个不相等就不是回文链表。
那么怎么才是全部相同呢?那就是把左右链表遍历一遍即可,当任意一边链表走到空了,则说明此链表是回文链表。
过程分析如下:
代码实现如下:
//求出中间结点
struct ListNode* MidListNode(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* reverseList(struct ListNode* head)
{
struct ListNode* cur=head;
struct ListNode* prev=NULL;
while(cur!=NULL)
{
struct ListNode* next=cur->next;
cur->next=prev;
prev=cur;
cur=next;
}
return prev;
}
bool isPalindrome(struct ListNode* head){
//先求出中间结点
struct ListNode* mid=MidListNode(head);
//然后以中间结点为开始,反转后面的结点
struct ListNode* headB=reverseList(mid);
struct ListNode* headA=head;
//接着开始对比两个链表是否相同
//不管链表结点是否是奇数还是偶数
//当任意一个链表走到空时,两个链表内容就全部相等,即是回文链表
while(headA && headB)
{
if(headA->val!=headB->val)
{
return false;
}
headA=headA->next;
headB=headB->next;
}
return true;
}