归并算法
这是leetcode中 148. 排序链表 ,难度为中等
题目描述
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
示例 1:
输入:head = [4,2,1,3]
输出:[1,2,3,4]
示例 2:
输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]
示例 3:
输入:head = []
输出:[]
提示:
链表中节点的数目在范围 [0, 5 * 104] 内
-105 <= Node.val <= 105
进阶:你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?
通过次数234,947提交次数352,622
来源:力扣(LeetCode)
链接:leetcode-cn.com/problems/so…
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
算法实现
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var sortList = function(head) {
//之前是对数组进行排序,这次是对链表进行排序
//使用冒泡排序,不过交换交换的时候需要注意,也不用怎么注意,直接交换值就可以,又不用交换节点 22点56分
//这个没有长度怎么使用冒泡
//遍历一遍,然后取出所有的值,然后再放进去?
// var res = []
// var cur = head
// //找出所有的值
// while(cur){
// res.push(cur.val)
// cur = cur.next
// }
// //从小到大进行排序
// res.sort((a,b)=>a-b)
// cur = head
// var i = 0
// //输入排序后的值
// while(cur){
// cur.val = res[i++]
// cur = cur.next
// }
// return head
//如果是上面的做法,行得通,但是不是符合刷题的目的
//看了题解后,是使用递归的算法,就是将链表两半,然后对链表进行排序组合,重复递归后,再进行排序
//合并两个有序链表
var merge = (list1,list2) => {
//从新列一个链表而不是在原来的基础上追加‘
var curNode = new ListNode(0);
var head = curNode
var cur1 = list1;
var cur2 = list2;
while(cur1 !== null && cur2 !==null){
//如果第一个比较小的,就把,给cur1链表,相同长度,或者长度相差一
if(cur1.val <= cur2.val){
head.next = cur1
cur1 = cur1.next
}else{
head.next = cur2
cur2 = cur2.next
}
//下一个头部
head = head.next
}
if(cur1 !== null){
head.next = cur1
}
if(cur2 !== null){
head.next = cur2
}
return curNode.next
}
//将链表进行划分,分为fast指针和show指针,fast先走两步,而show指针只是走一步,如果fast先到的话,说明show到了中点,然后return 这个中间点
var tosort = (list,tail) =>{
//需要加上判断,才能够进行返回
if(list == null) return list
if(list.next == tail){
//重复了,如果两个数的话,就不用进行划分了
list.next = null
return list
}
var cur = list;
var fast = cur;
var show = cur;
var mid ;
//如果fast跟尾部相同的时候,
while(fast !== tail){
show = show.next
fast = fast.next
if(fast !== tail){
fast = fast.next
}
}
mid = show
return merge(tosort(cur,mid), tosort(mid,tail))
}
return tosort(head,null)
};
复杂度分析
时间复杂度:O(nlogn)
空间复杂度:O(logn)
最后
这是我2022年分享的「leetcode」第NO.7篇文章。