目录
1.LeetCode203.移除链表元素
方法一:双指针
方法二:创建新链表
方法三:递归
2.LeetCode206.反转链表
方法一:创建新链表
方法二:三指针
方法三:递归
3.LeetCode876.链表的中间节点
解法:快慢指针
4.牛客网JZ22:链表中倒数第k个结点
解法:快慢指针
5.LeetCode21.合并两个有序链表
方法一:创建新链表
方法二:递归
设两个指针prev和cur,让cur指向头,prev指向空,依次删除节点值为val的节点
//方法一:双指针
struct ListNode*cur=head,*prev=NULL;
while(cur){
if(cur->val==val){
if(cur==head){
head=cur->next;
free(cur);
cur=head;
}else{
prev->next=cur->next;
free(cur);
cur=prev->next;
}
}else{
prev=cur;
cur=cur->next;
}
}
return head;
遍历链表,让不是val值的节点尾插到新链表
//方法二:创建新链表
struct ListNode*newhead=(struct ListNode*)malloc(sizeof(struct ListNode));
newhead->next=NULL;
struct ListNode*tail=newhead;
struct ListNode*cur=head;
while(cur){
if(cur->val==val){
struct ListNode*next=cur->next;
free(cur);
cur=next;
}else{
tail->next=cur;
tail=tail->next;
cur=cur->next;
}
}
tail->next=NULL;
return newhead->next;
1.判断头结点,若满足条件则删除
2.将头结点后视为一个链表2
3.递归删除链表2(递归1-3步)
4.返回头结点
//方法三:递归
if(head==NULL)return NULL;
while(head&&head->val==val){
struct ListNode*next=head->next;
free(head);
head=next;
}
if(head)head->next=removeElements(head->next,val);
return head;
创建一个指针变量newlist让它指向头指针head,创建指针cur指向头结点的下一个结点,让头指针指向NULL,用next指针指向cur结点的下一个结点。如图:
由图将右链表依次头插到左链表即可 ,最后返回*newlist或head即可。
//方法一:创建新链表
if(head==NULL)return NULL;
struct ListNode**newlist=&head;
struct ListNode*cur=head->next;
head->next=NULL;
while(cur){
struct ListNode*next=cur->next;
cur->next=(*newlist);
*newlist=cur;
cur=next;
}
return (*newlist);
创建三个分别指向当前结点、前驱结点、和下一个结点的指针变量,前驱结点开始时指向头结点,让当前结点指向前驱结点,然后让三个指针往后走,直到当前结点指向空。
//方法三 三指针
struct ListNode* reverseList(struct ListNode* head){
if(head==NULL||head->next==NULL)return head;
struct ListNode*pre=NULL,*cur=head,*next=head->next;
while(cur){
cur->next=pre;
pre=cur;
cur=next;
if(next)
next=next->next;
}
return pre;
}
1.让tail指针指向头结点的下一个结点。p为以tail下一个结点开始的链表反转后的头结点的地址,也是链表反转后的地址。
2.让head指针指向空节点
3.让tail指向头结点
4.返回p
//2.递归实现
if(head==NULL||head->next==NULL)return head;
struct ListNode*tail=head->next,*p=reverseList(tail);
head->next=NULL;
tail->next=head;
return p;
快指针走两步,慢指针走一步,快指针走完,慢指针就指向中间节点了。
struct ListNode* middleNode(struct ListNode* head){
if(head==NULL||head->next==NULL)return head;
struct ListNode*fast=head,*slow=head;
while(fast!=NULL&&fast->next!=NULL){
fast=fast->next->next;
slow=slow->next;
}
return slow;
}
让快指针先走k步,然后两指针再一起走,快指针走完,慢指针就指向链表中倒数第k个节点。
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
// write code here
if(pListHead==NULL||pListHead->next==NULL)return pListHead;
struct ListNode*fast=pListHead,*slow=pListHead;
while(k--){
if(fast==NULL)return NULL;
fast=fast->next;
}
while(fast){
fast=fast->next;
slow=slow->next;
}
return slow;
}
让cur1,cur2指针分别指向两个链表的头结点,将cur结点的值小的节点尾插到新链表上,并让cur指针往后走,直到有一个cur指针指向空为止。
//方法一:创建新链表
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
if(list1==NULL||list2==NULL)return list1==NULL?list2:list1;
struct ListNode*cur1=list1,*cur2=list2;
struct ListNode*newlist;
if(cur1->valval){
newlist=cur1;
cur1=cur1->next;
}
else{
newlist=cur2;
cur2=cur2->next;
}
struct ListNode*tail=newlist;
while(cur1&&cur2){
if(cur1->valval){
tail->next=cur1;
cur1=cur1->next;
tail=tail->next;
}else{
tail->next=cur2;
cur2=cur2->next;
tail=tail->next;
}
}
if(!cur1)
tail->next=cur2;
else
tail->next=cur1;
return newlist;
}
1.判断list1和list2结点的值大小关系,若list1的值小,让list1节点为头结点。(若list2的值小则list2做头结点,以下步骤反之)
2.合并以list1->next和list2分别做头节点的两个链表(递归实现),返回合并后链表的头结点,让list1的下个节点为该节点。
3.返回list1作为头结点。
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
if(list1==NULL||list2==NULL)return list1==NULL?list2:list1;
if(list1->valval){
list1->next=mergeTwoLists(list1->next,list2);
return list1;
}
else {
list2->next=mergeTwoLists(list1,list2->next);
return list2;
}
}