赞
踩
作者:旧梦拾遗186
专栏:数据结构成长日记
每日励志:
你没资格半途而废,你没资格破罐子破摔,你只能让自己活得比任何人都好,比任何人都强大,你已经没有退路。
前言:
小编带大家学习链表OJ题。
目录
移除链表元素https://leetcode.cn/problems/remove-linked-list-elements/
给你一个链表的头节点
head
和一个整数val
,请你删除链表中所有满足Node.val == val
的节点,并返回 新的头节点 。示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]示例 2:
输入:head = [], val = 1 输出:[]示例 3:
输入:head = [7,7,7,7], val = 7 输出:[]提示:
- 列表中的节点数目在范围
[0, 104]
内1 <= Node.val <= 50
0 <= val <= 50
思路一:一种比较普遍的方式,边遍历边找不同。我们可以通过定义两个指针,一个指向头节点,一个置为NULL。当遇到值为相同的时候,直接跳过去。指向下一位。同时,我们要去注意头删的问题,因为题目中给出的函数具有头结点head。
struct ListNode* removeElements(struct ListNode* head, int val){ struct ListNode* cur=head; struct ListNode* pre=NULL; while(cur) { if(cur->val==val) { if(cur==head) { head=head->next; free(cur); cur=head; } else { pre->next=cur->next; free(cur); cur=pre->next; } } else { pre=cur; cur=cur->next; } } return head; }
思路二:给一个新的链表,不是val的结点尾插到新链表即可。最后结点置为NULL。同时,还是要注意头结点的问题
struct ListNode* removeElements(struct ListNode* head, int val){ struct ListNode* cur=head; struct ListNode* tail=NULL; struct ListNode* newnode=NULL; while(cur) { if(cur->val!=val) { if(tail==NULL) { newnode=tail=cur; } else { tail->next=cur; tail=tail->next; } cur=cur->next; } else { struct ListNode* del=cur; cur=cur->next; free(del); } } if(tail) { tail->next=NULL; } return newnode; }
我们不难发现,如果没有头结点,我们都要去关注,所以我们可以给出带头结点(哨兵链表)的单链表来进行实现:
struct ListNode* removeElements(struct ListNode* head, int val){ struct ListNode*cur = head; struct ListNode*guard = (struct ListNode*)malloc(sizeof(struct ListNode)); struct ListNode*tail = guard; while(cur) { if(cur->val != val) { // tail=cur; tail->next = cur; tail = tail->next; cur = cur->next; } else { struct ListNode*del = cur; cur = cur->next; free(del); } } if(tail) tail->next = NULL; head = guard->next; free(guard); return head; }有头结点之后我们就不需要去考虑删除第一个元素的事了。
反转链表https://leetcode.cn/problems/reverse-linked-list/
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:
输入:head = [1,2]
输出:[2,1]
示例 3:输入:head = []
输出:[]
提示:
链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000
进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?
思路一:取结点头插到新的结点
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; }
思路二:直接把指针的方向进行翻转即可,使得链表翻转
struct ListNode* reverseList(struct ListNode* head){ struct ListNode* cur=head; struct ListNode* pre=NULL; while(cur) { struct ListNode* next=cur->next; cur->next=pre; pre=cur; cur=next; } return pre; }
力扣https://leetcode.cn/problems/merge-two-sorted-lists/description/
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:输入:l1 = [], l2 = []
输出:[]
示例 3:输入:l1 = [], l2 = [0]
输出:[0]
提示:
两个链表的节点数目范围是 [0, 50]
-100 <= Node.val <= 100
l1 和 l2 均按 非递减顺序 排列来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/merge-two-sorted-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:比较简单,创建一个带头结点的链表,去比较数据的大小尾插到新链表的后面即可。
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){ struct ListNode* cur1=list1; struct ListNode* cur2=list2; struct ListNode* guard=(struct ListNode*)malloc(sizeof(struct ListNode)); guard->next=NULL; struct ListNode* tail=guard; while(cur1&&cur2) { if(cur1->val<cur2->val) { tail->next = cur1; cur1 = cur1->next; } else { tail->next = cur2; cur2 = cur2->next; } tail = tail->next; } if(cur1) { tail->next=cur1; } if(cur2) { tail->next=cur2; } struct ListNode* head=guard->next; free(guard); return head; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。