几道简单的链表题
Posted 小倪同学 -_-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了几道简单的链表题相关的知识,希望对你有一定的参考价值。
1.删除链表指定值
题目简介
给你一个链表的头节点head和一个整数 val ,请你删除链表中所有满足Node.val == val的节点,并返回新的头节点 。
LeetCode 203
思路分析
创建一个新链表,将原链表中所有数值不是val的结点尾插到新链表上。
代码实现
struct ListNode* removeElements(struct ListNode* head, int val){
if(head==NULL)
return NULL;
struct ListNode* newhead=NULL,*tail=NULL;
struct ListNode* cur=head;
while(cur)
{
struct ListNode* next=cur->next;
if(cur->val==val)
{
free(cur);
}
else
{
if(tail==NULL)
{
newhead=tail=cur;
}
else
{
tail->next=cur;
tail=cur;
}
}
cur=next;
}
if(tail)
tail->next=NULL;
return newhead;
}
2.反转一个单链表
题目简介
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
思路分析
思路一:调整前后指针的指向。
思路二:创建一个新链表,将原链表头插到新链表上
代码实现
//思路一
struct ListNode* reverseList(struct ListNode* head){
//空链表
if (head == NULL)
return NULL;
struct ListNode* n1, *n2, *n3;
n1 = NULL;
n2 = head;
n3 = head->next;
while (n2)
{
n2->next = n1;
n1 = n2;
n2 = n3;
if (n3)
n3 = n2->next;
}
return n1;
}
//思路二
struct ListNode* reverseList(struct ListNode* head){
struct ListNode* cur = head;
struct ListNode* newnode = NULL;
//头插
while(cur)
{
struct ListNode* next=cur->next;
cur->next=newnode;
newnode=cur;
cur=next;
}
return newnode;
}
3.找链表中间结点
题目简介
给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
思路分析
利用快慢指针,快指针一次走两步,慢指针一次走一步,当快指针走到尾结点时,慢指针正好在中间结点处
代码实现
struct ListNode* middleNode(struct ListNode* head){
struct ListNode* fast,*slow;
fast=slow=head;
//找结点
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
4.找倒数第K个结点
题目简介
思路分析
创建快慢指针,快指针先走K步,然后快慢指针一起走,当快指针走到尾结点时,慢指针的位置正好是倒数第K个结点的位置
代码实现
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
// write code here
struct ListNode* fast, *slow;
fast =slow =pListHead;
while (k--)
{
if (fast == NULL)
return NULL;
fast = fast->next;
}
while (fast != NULL)
{
fast = fast->next;
slow = slow->next;
}
return slow;
}
5.合并两个有序链表
题目简介
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
思路分析
创建一个新链表,比较两个链表结点的值,将较小值尾插到新链表上。
代码实现
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
//判断l1是否为NULL,若是直接返回l2
if (l1 == NULL)
return l2;
if (l2 == NULL)
return l1;
struct ListNode* n1 = l1, *n2 = l2;
struct ListNode* newhead = NULL, *tail = NULL;
//取一个较小值做头结点
if (n1->val<n2->val)
{
newhead = tail = n1;
n1 = n1->next;
}
else
{
newhead = tail = n2;
n2 = n2->next;
}
//尾插
while (n1&&n2)
{
if (n1->val<n2->val)
{
tail->next = n1;
tail = tail->next;
n1 = n1->next;
}
else
{
tail->next = n2;
tail = tail->next;
n2 = n2->next;
}
}
//n1为NULL时,直接将n2剩下结点尾插
if (n1)
tail->next = n1;
if (n2)
tail->next = n2;
return newhead;
}
6.求相交链表的相交结点
题目简介
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
思路分析
先计算两个链表的长度,并取其差值的绝对值,让长链表先走差值步,然后两链表同时走,当两链表结点相同时,该结点就为相交结点
代码实现
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct ListNode* curA=headA;
struct ListNode* curB=headB;
int lenA=0,lenB=0;
while(curA)
{
++lenA;
curA=curA->next;
}
while(curB)
{
++lenB;
curB=curB->next;
}
struct ListNode* LongList=headA;
struct ListNode* ShortList=headB;
if(lenA<lenB)
{
LongList=headB;
ShortList=headA;
}
//让长的走差距步
int gap=abs(lenA-lenB);
while(gap--)
{
LongList = LongList->next;
}
//同时走找交点
while(ShortList && LongList)
{
if(ShortList==LongList)
{
return ShortList;
}
ShortList=ShortList->next;
LongList=LongList->next;
}
//不相交
return NULL;
}
以上是关于几道简单的链表题的主要内容,如果未能解决你的问题,请参考以下文章