目录
题目一、链表的中间结点
给你单链表的头结点 head
,请你找出并返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
1 、核心算法思想
如果题目要求只能遍历一遍,我们可以用两个指针,一个每次走一步,一个每次走两步,当走两步的指针走到尾时,走一步的指针就在中间。
2、代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* middleNode(struct ListNode* head){
struct ListNode*slow,*fast;
slow=fast=head;
while(fast!=NULL&&fast->next!=NULL)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
题目二、链表中倒数第k个数
输入一个链表,输出该链表中倒数第k个结点。
1、核心算法思想
第一种:
用两个指针fast和slow,fast先走k-1步,然后再两个一起走,当fast走到尾时,slow就到了倒数第k的位置了(为什么?因为倒数第一个和倒数第k个的距离为k-1)。
第二种:
fast先走k步,再一起走,当fast走到NULL时,slow就是k。
2、代码
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/**
*
* @param pListHead ListNode类
* @param k int整型
* @return ListNode类
*/
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
// write code here
struct ListNode*fast,*slow;
fast=slow=pListHead;
if(pListHead==NULL||k==0)
{
return NULL;
}
while(k--)
{
if(fast==NULL)
{
return NULL;
}
fast=fast->next;
}
while(fast)
{
fast=fast->next;
slow=slow->next;
}
return slow;
}
题目三、反转一个单链表
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
1、核心算法思想
主要就是头插。需要注意的是要记录下一个结点的位置再把这个结点放过去。同时还应记录新链表的头。
2、代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
struct ListNode*cur=head;
struct ListNode*newhead=NULL;
while(cur)
{
struct ListNode*next=cur->next;
cur->next=newhead;
newhead=cur;
cur=next;
}
return newhead;
}
题目四、合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
1、核心算法思想
每条链表一个指针,比较大小,小的放新链表(尾插),同时往后走,再比较……,直到其中一个指针走到空,停下,把没走完的补过去。
为了避免每次都要找尾,我们用tail把尾记录下来。
2、代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
struct ListNode*cur1=list1,*cur2=list2;
struct ListNode*head=NULL,*tail=NULL;
if(list1==NULL)
return list2;
if(list2==NULL)
return list1;
while(cur1&&cur2)
{
if(cur1->val<cur2->val)
{
if(head==NULL)
{
head=tail=cur1;
}
else
{
tail->next=cur1;
tail=tail->next;
}
cur1=cur1->next;
}
else
{
if(head==NULL)
{
head=tail=cur2;
}
else
{
tail->next=cur2;
tail=tail->next;
}
cur2=cur2->next;
}
if(cur1)
{
tail->next=cur1;
}
if(cur2)
{
tail->next=cur2;
}
}
return head;
}