OJ练习第60题——合并 K 个升序链表
Posted 盖盖的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OJ练习第60题——合并 K 个升序链表相关的知识,希望对你有一定的参考价值。
合并 K 个升序链表
题目描述
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例
示例 1:
输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
示例 2:
输入:lists = []
输出:[]
Java代码1
/**
* Definition for singly-linked list.
* public class ListNode
* int val;
* ListNode next;
* ListNode()
* ListNode(int val) this.val = val;
* ListNode(int val, ListNode next) this.val = val; this.next = next;
*
*/
class Solution
ListNode[] lists;
public ListNode mergeKLists(ListNode[] lists)
this.lists = lists;
if(lists==null || lists.length==0) return null;
return divide(0,lists.length-1);
public ListNode divide(int start,int end)
// 递归终止条件:如果start==end ,终止
if(start==end) return lists[start];
// 1. 计算中间值下标
int mid = (start+end)/2;
// 2. 分治左边区间
ListNode left = divide(start,mid);
// 3. 分治右边区间
ListNode right = divide(mid+1,end);
// 4. 合并这两个区间
return merge(left,right);
// 合并两个有序 链表
public ListNode merge(ListNode l1,ListNode l2)
ListNode res = new ListNode(-1);
ListNode cur = res;
while(l1!=null && l2!=null)
if(l1.val<=l2.val)
cur.next=l1;
l1 = l1.next;
else
cur.next = l2;
l2=l2.next;
cur = cur.next;
if(l1!=null)
cur.next = l1;
if(l2!=null)
cur.next = l2;
return res.next;
Java代码2
class Solution
public ListNode mergeKLists(ListNode[] lists)
if(lists.length == 0) return null;
ListNode[] list1 = new ListNode[lists.length - 1];
System.arraycopy(lists, 1, list1, 0, lists.length - 1);
return mergeTwoLists(lists[0], mergeKLists(list1));
public ListNode mergeTwoLists(ListNode list1, ListNode list2)
if(list1 == null) return list2;
if(list2 == null) return list1;
ListNode head = list1.val <= list2.val ? list1 : list2;
head.next = mergeTwoLists(head.next, list1.val <= list2.val ? list2 : list1);
return head;
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/merge-k-sorted-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
链表OJ题练习2
链表OJ习题2
链表的倒数第N个节点(双指针)
链接:删除链表的倒数第 N 个结点
问题描述
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
进阶:
你能尝试使用一趟扫描实现吗?
方法1分析:
- 我们可以在遍历链表的同时将所有节点依次入栈。
- 根据栈「先进后出」的原则,我们弹出栈的第 n 个节点就是需要删除的节点,并且目前栈顶的节点就是待删除节点的前驱节点
(需要自己建栈,这里不再赘述
)
方法2分析:
- 先让快指针走n步,再快慢指针同时走,同时记录慢指针的前一个节点
- 直到快指针为NULL时 让记录的慢指针的前一个节点指向慢指针的后一个节点
代码如下:
struct ListNode* removeNthFromEnd(struct ListNode* head, int n){ if(head->next==NULL) { return NULL; } struct ListNode* newhead=(struct ListNode* )malloc(sizeof(struct ListNode)); newhead->next=head; struct ListNode* prev=newhead; struct ListNode* fast=head; struct ListNode* slow=prev->next; while(n--) { fast=fast->next; } while(1) { if(fast==NULL) { prev->next=slow->next; break; } slow=slow->next; prev=prev->next; fast=fast->next; } return newhead->next; }
合并 K个升序链表
链接:删除链表的倒数第 N 个结点
问题描述
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
思路一
:(暴力法)
- 将链表数组中的每个链表中的节点值存到一个新建的数组中,然后对数组排序,再建一个新链表进行存储
思路二
:(小根堆)
思路三
:(分而治之)
代码如下在这里插入代码片
旋转链表
链接:删除链表的倒数第 N 个结点
问题描述:
给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
思路一:
(双指针)
思路二:
(环形链表)
- 先循环得出链表的长度,同时顺便让尾的next指向head构成环形
- 由head开始两两交换,一个循环进行n次,共(k%n)个循环
代码如下:struct ListNode* rotateRight(struct ListNode* head, int k){ if(head==NULL) { return NULL; } struct ListNode* cac=head; //struct ListNode* cur=head; int n=0; while(1) { if(cac->next==NULL) { n++; break; } cac=cac->next; n++; } printf("%d\\n",n); if(0==k%n) return head; cac->next=head;//构造环形链表 int times=k%n+1; while(--times) { struct ListNode* cur=head; int tmp=cur->val; for(int i=0;i<=n;i++) { struct ListNode* next=cur->next; int tem=next->val; next->val=tmp; tmp=tem; cur=next; } } struct ListNode* cur2=head; while(--n) { cur2=cur2->next; } cur2->next=NULL; return head; }
以上是关于OJ练习第60题——合并 K 个升序链表的主要内容,如果未能解决你的问题,请参考以下文章
#yyds干货盘点# LeetCode 腾讯精选练习 50 题:合并K个升序链表
精选力扣500题 第18题 LeetCode 23. 合并K个升序链表c++详细题解
数据结构之超硬核热门复杂度数组链表OJ题2W+文字+图片详解
Leetcode练习(Python):链表类:第21题:合并两个有序链表:将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。