前言
hello,大家好呀,我是Humble,本篇博客要分享的内容是关于链表的一些力扣OJ题
OK,废话不多说,我们直接开始吧~
题目一
203. 移除链表元素 - 力扣(LeetCode)
题目描述:
给你一个链表的头节点
head
和一个整数val
,请你删除链表中所有满足Node
val == val
的节点,并返回 新的头节点
思路一:遍历原链表,遇到val就执行删除 val 节点的操作
这是一种很容易想到的思路,BUT,执行删除操作修改指针的指向有点麻烦,有没有其他办法?
接下来我们看一下思路二:
定义新链表,遍历原链表找不为val的节点,尾插在新链表上
代码如下:
struct ListNode* removeElements(struct ListNode* head, int val)
{
struct ListNode* newHead = NULL;
struct ListNode* newTail = NULL;
struct ListNode* pcur = head;//pur用来遍历链表
while(pcur)
{
if (pcur->val!=val)
{
if (newHead == NULL)//链表为空
newHead = newTail = pcur;
else
{
newTail->next = pcur;
newTail = newTail->next;
}
}
pcur = pcur->next;
}
if (newTail) newTail->next = NULL; //循环结束后让尾节点指向空指针
return newHead;
}
运行结果:
题目二
206. 反转链表 - 力扣(LeetCode)
题目描述
给你单链表的头节点
head
,请你反转链表,并返回反转后的链表
这里有一个点值得注意,链表的指针是只能指向后面的,不能反过来,这也是它的一个特性
思路:创建三个指针n1,n2,n3分别记录前驱节点,当前节点,后继节点,改变原链表指针指向
代码如下:
struct ListNode* reverseList(struct ListNode* head)
{
if (head == NULL) //如果是空链表,直接返回
return head;
struct ListNode* n1, *n2, *n3;
n1 = NULL;
n2 = head;
n3 = head->next;
while (n2)
{
n2->next = n1;
n1 = n2;
n2 = n3;
if (n3) n3 = n3->next;
}
return n1;
}
运行结果如下:
题目三
21. 合并两个有序链表 - 力扣(LeetCode)
题目描述:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
对于这道题,我们很直接的会想到要创建一个新链表
而且,如果有看过我的上一篇关于顺序表的算法OJ题博客的小伙伴可能会发现,
本题与那里的题目二——合并两个有序数组有点相像
下面是这道题的代码:
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
if (list1 == NULL) return list2;
if (list2 == NULL) return list1;
struct ListNode* l1 = list1;
struct ListNode* l2 = list2;
struct ListNode* newHead,*newTail;
newHead = newTail = (struct ListNode*)malloc(sizeof(struct ListNode));
while (l1 && l2)
{
if (l1->val < l2->val)
{
newTail->next = l1;
newTail = newTail->next;
l1 = l1->next;
}
else
{
newTail->next = l2;
newTail = newTail->next;
l2 = l2->next;
}
}
if (l1) newTail->next = l1;
if (l2) newTail->next = l2;
struct ListNode* ret = newHead->next;
free(newHead);
return ret;
}
运行结果:
题目四
876. 链表的中间结点 - 力扣(LeetCode)
题目描述:
给你单链表的头结点
head
,请你找出并返回链表的中间结点如果有两个中间结点,则返回第二个中间结点
对于这道题,Humble的思路是快慢指针
定义两个变量slow和fast
slow每走一步,fast走两步
代码如下:
struct ListNode* middleNode(struct ListNode* head)
{
struct ListNode* slow,*fast;
slow = fast =head;
while(fast && fast->next) //两个条件顺序不能换!
{
slow = slow->next;//slow走一步
fast = fast->next->next;//fast走两步
}
return slow;
}
运行结果如下:
题目五
面试题 02.04. 分割链表 - 力扣(LeetCode)
题目描述:
给你一个链表的头节点
head
和一个特定值x
,请你对链表进行分隔,使得所有 小于x
的节点都出现在 大于或等于x
的节点之前
对于这道题,Humble的思路是:定义两个链表,分别放 小于 x
的 与 大于或等于 x
的
通过遍历原链表分别放进对应的新链表中,最后两个链表按顺序首尾相连
代码如下:
struct ListNode* partition(struct ListNode* head, int x)
{
if (head ==NULL) //空链表直接返回
return head;
struct ListNode*greaterHead,*greaterTail;
struct ListNode*lessHead,*lessTail;
greaterHead = greaterTail = (struct ListNode*)malloc(sizeof(struct ListNode));
lessHead = lessTail = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* pcur = head;
while (pcur)
{
if (pcur ->val <x)
{
lessTail->next = pcur;
lessTail = lessTail->next;
}
else
{
greaterTail->next = pcur;
greaterTail = greaterTail->next;
}
pcur = pcur->next;
}
greaterTail->next = NULL;//将大链表尾部置为NULL,防止链表循环
lessTail->next = greaterHead->next;
return lessHead->next;
}
运行结果如下:
结语
好了,今天关于链表的五道OJ题的分享就到这里了,如果对大家有帮助就太好啦~
在学习编程的道路上Humble与各位同行,加油吧各位!
最后希望大家点个免费的赞或者关注吧(感谢感谢),也欢迎大家订阅我的专栏
让我们在接下来的时间里一起成长,一起进步吧!