Leetcode之148. Sort List Medium
https://leetcode.com/problems/sort-list/
Sort a linked list in O(n log n) time using constant space complexity.
Example 1:
Input: 4->2->1->3
Output: 1->2->3->4
Example 2:
Input: -1->5->3->4->0
Output: -1->0->3->4->5
下面代码参考连接:
/**
* Merge sort use bottom-up policy,
* so Space Complexity is O(1)
* Time Complexity is O(NlgN)
* stable sort
*/
/*
* 解决该题需要使用归并排序,而这里的归并排序需要使用自底向上策略;
这样才能实现,空间复杂度O(1),时间复杂度O(NlgN)
*/
class Solution {
public:
ListNode *sortList(ListNode *head) {
if(!head || !(head->next)) return head; // 判断传入的链表头结点是否为空或者链表是否只有一个元素 //get the linked list's length
// 下面代码将得到链表的长度
ListNode* cur = head;
int length = ;
while(cur){
length++;
cur = cur->next;
} //设定一个虚节点,并指向头结点,方便后续操作
ListNode dummy(); // 我不太喜欢这么创建结点的方式,更喜欢如:ListNode* dummy = new ListNode(0)
dummy.next = head;
// 创建三个节点指针:left用来存放切分后第一部分链表的头结点,right用来存放第二部分的头结点,tail用来存放归并之后的有序链表的尾节点(方便下面的拼接)
ListNode *left, *right, *tail;
for(int step = ; step < length; step <<= ){ // 左移代表乘以2
/**
* 初次遍历的时候,由于dummy.next等于头指针,所以cur初次的值是头指针;但是cur主要用来存放什么呢?
* 从下面的while循环可以看出端倪:每次都是以步长step为基准,对链表进行切分(split(left, step)),使链表分为两部分,前面的一部分包含step个元素;后面是剩下的链表(len - step个元素),对后面这个链表同理,也做了一次切分(split(right, step)),此时的最后一部分链表的头指针由cur来存放。
* 简单一句话:每一次while循环都需要切两次,而cur用来存放最后一次切分的剩下的链表的头结点。而剩下这部分链表是没有排序和归并的(还是杂乱无章)
* 此外,值得注意的是while循环在for循环里,也就是每一个step,链表都会遍历的执行,实现step内的元素有序。
* while循环将链表变成一段一段有序的了(step长度为一段)
**/
cur = dummy.next;
tail = &dummy;
while(cur){
left = cur;
right = split(left, step);
cur = split(right,step);
tail = merge(left, right, tail);
}
}
return dummy.next;
}
private:
/**
* Divide the linked list into two lists,
* while the first list contains first n ndoes
* return the second list's head
*/
/*
* split函数将链表分成两部分链表,
* 第一部分链表分包含n个节点,函数最后返回第二部分链表的头结点
*/
ListNode* split(ListNode *head, int n){
//if(!head) return NULL;
// 遍历到第n个节点,后面就可以实现将第n个节点和第n+1个节点断开
for(int i = ; head && i < n; i++) head = head->next; if(!head) return NULL;
// 下面两行实现断开这个操作
ListNode *second = head->next;
head->next = NULL;
return second;
}
/**
* merge the two sorted linked list l1 and l2,
* then append the merged sorted linked list to the node head
* return the tail of the merged sorted linked list
*/
/*
* 将两个排好序的链表l1和l2进行合并
* 然后将合并好的新链表连接到传入的head节点之后
* 最后返回归并排序好后的有序链表的尾节点
*/
ListNode* merge(ListNode* l1, ListNode* l2, ListNode* head){
ListNode *cur = head; // 这里的cur相当于下面一步步合并出来的有序链表的尾结点,去连接下一个该存放的节点,并更新
while(l1 && l2){
if(l1->val > l2->val){
cur->next = l2;
cur = l2;
l2 = l2->next;
}
else{
cur->next = l1;
cur = l1;
l1 = l1->next;
}
}
cur->next = (l1 ? l1 : l2); // 将还有元素的部分链表连接到后面
while(cur->next) cur = cur->next; // 得到尾结点
return cur;
}
};
第一次写博客,在注释中啰嗦了这么多,才明白为什么大部分人不喜欢在代码中通过注释把事情说明白,因为太难了!
即使写了这么多,我依然觉得读者可能需要在理解代码的基础上才能看得懂注释,所以,理解代码没有捷径,就是干!
当然,代码中注释的使命是为了简单提醒,做到简洁明了是最好的风格。这里写这么多废话主要是为了更快理解这个人写的代码,希望这个目的达成了!

Leetcode之148. Sort List Medium的更多相关文章
- 【LeetCode】148. Sort List 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- 【leetcode】148. Sort List
Sort a linked list in O(n log n) time using constant space complexity. 链表排序可以用很多方法,插入,冒泡,选择都可以,也容易实现 ...
- 【刷题-LeetCode】148 Sort List
Sort List Sort a linked list in O(n log n) time using constant space complexity. Example 1: Input: 4 ...
- [leetcode] 147. Insertion Sort List (Medium)
原题 别人的思路 非常简洁 function ListNode(val) { this.val = val; this.next = null; } /** * @param {ListNode} h ...
- C#版 - LeetCode 148. Sort List 解题报告(归并排序小结)
leetcode 148. Sort List 提交网址: https://leetcode.com/problems/sort-list/ Total Accepted: 68702 Total ...
- [LeetCode] 148. Sort List 链表排序
Sort a linked list in O(n log n) time using constant space complexity. Example 1: Input: 4->2-> ...
- 148. Sort List - LeetCode
Solution 148. Sort List Question 题目大意:对链表进行排序 思路:链表转为数组,数组用二分法排序 Java实现: public ListNode sortList(Li ...
- [array] leetcode - 40. Combination Sum II - Medium
leetcode - 40. Combination Sum II - Medium descrition Given a collection of candidate numbers (C) an ...
- [LeetCode] 324. Wiggle Sort II 摆动排序 II
Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]... ...
随机推荐
- [Dart] final vs const
void main() { ; print(a); ; print(b); final c = 'Hello'; // c = 'Hello again'; // Uncomment to throw ...
- PHP流程控制之嵌套if...else...elseif结构
还记得本章开篇我们讲了一个王思总同学的例子: 王同学是生活极度充满娱乐化和享受生活的人.他抵达北京或者大连的时候做的事,他抵达后做的事情,如下:直线电机参数 半夜到达,先去夜店参加假面舞会 早上抵达, ...
- PHP基础语法之 位运算
写了几年PHP的人都好奇说,没有用过位运算符.所以,此处你看二进制看的头晕,就去T¥M¥D吧. 位运算符基本不用,我们也将这个知识设置为了解级别.位运算符的知识点,你不想学习也可以.等以后用到位运算的 ...
- P3410 拍照
漂亮小姐姐点击就送:https://www.luogu.org/problemnew/show/P3410 题目描述 小B有n个下属,现小B要带着一些下属让别人拍照. 有m个人,每个人都愿意付给小B一 ...
- shell 边边角角
[Shell学习笔记] 数组.关联数组和别名使用 Linux中bash脚本数组和字典使用举例 Linux Shell 通配符.元字符.转义符使用实例介绍
- Pythton3实例
计算1-100之和 #add.py n = 0 sum = 0 for n in range(0,101): sum += n print(sum) 实现99乘法法则 #mul.py i = 1 wh ...
- 10月清北学堂培训 Day 5
今天是廖俊豪老师的讲授~ T1 第一次想出正解 30 pts: k <= 10,枚举如何把数放到矩阵中,O ( k ! ): 100 pts: 对于矩阵的每一列,我们二分最小差异值,然后贪心去判 ...
- HDU 6041 I Curse Myself ——(仙人掌图,tarjan,转化)
题解见这个博客:http://blog.csdn.net/ME495/article/details/76165039. 复杂度不太会算..这个经典问题的解法需要注意,维护队列里面只有k个元素即可.另 ...
- [WEB安全]给BurpSuite设置非本地的网络代理
目录 0x01 一般情况 0x02 移动端流量抓取 0x03 多重代理的情形 0x04 参考链接 在Web渗透测试过程中,BurpSuite是不可或缺的神器之一. BurpSuite的核心是代理Pro ...
- Linux信号使用及自定义信号
linux自定义信号:https://www.cnblogs.com/bigben0123/p/3186661.html linux信号.值及解释:https://blog.csdn.net/luot ...