归并排序能够有两种思路----top-down 和 bottom-up

top-down:

递归实现,将数组分成两半。分别处理。再合并。

伪代码例如以下:

split ( A[], l, r)
{
if ( r - l < 2) return;
m = (r + l) / 2;
split ( A, l, m); //split A[l…m-1]
split ( A, m, r); //split A[m…r-1]
merge ( A, l, m, e); //merge A[l…m-1] and A[m…e-1]
}

bottom-up:

循环实现。将数组看做n个长度为1的组数组。

用width控制每次merge的子数组长度。width每次翻倍

伪代码例如以下:

sort ( A[], n)
{
for (width = 1; width < n; width *= 2)
{
for (i = 0; i < n; i += 2 * width)
{
merge(A, i, min(i + width, n), min(i + 2 * width, n));
}
}
}

Sort list中使用链表。不能在O(1)的时间内訪问随意节点,同一时候注意要处理尾部节点的next,置为NULL

和上面的伪代码类似,首先实现merge函数:

    ListNode * merge(ListNode * h1, int s1, ListNode * h2, int s2)
{
if (h2 == NULL) return h1;
ListNode * h;
if (h1->val < h2->val)
h = advance(h1, s1);
else
h = advance(h2, s2);
ListNode * cur = h;
while (s1 && s2)
{
if (h1->val < h2->val)
cur->next = advance(h1, s1);
else
cur->next = advance(h2, s2);
cur = cur->next;
}
if (s1)
{
cur->next = h1;
while(s1) advance(h1, s1);
}
if (s2)
{
cur->next = h2;
while(s2) advance(h2, s2);
}
return h;
} ListNode * advance(ListNode * (& n), int & size)
{
ListNode * temp = n;
if (size == 1) n->next = NULL;
n = n->next;
size--;
return temp;
}

同一时候实现工具函数,訪问任何位置节点

ListNode * getNode(ListNode * head, int len)
{
while (len -- && head) head = head->next;
return head;
}

循环版本号主函数例如以下:

ListNode *sortList(ListNode *head) {
ListNode * cur = head;
int size = 0;
while (cur)
{
size ++;
cur = cur->next;
} ListNode * pre;
for (int w = 1; w <= size; w *= 2)
{
cur = head;
for (int i = 0; i < size; i+= w*2)
{
ListNode * h1 = cur, * h2 = getNode(cur, w), * next = getNode(cur, 2 * w);
cur = merge(h1, min(w, size - i), h2, min(w, size - i - w));
if (i == 0)
head = cur;
else
pre->next = cur;
pre = getNode(cur, min(2 * w, size - i) - 1);
cur = next;
}
}
return head;
}

递归版本号主函数例如以下:

    ListNode *sortList(ListNode *head) {
ListNode * cur = head;
int size = 0;
while (cur)
{
size ++;
cur = cur->next;
}
return sort(head, size - size / 2, getNode(head, size - size / 2), size / 2);
} ListNode * sort(ListNode * h1, int s1, ListNode * h2, int s2)
{
if (s1 == 0) return h2;
if (s2 == 0) return h1;
h1 = sort(h1, s1 - s1 / 2, getNode(h1, s1 - s1 / 2), s1 / 2);
h2 = sort(h2, s2 - s2 / 2, getNode(h2, s2 - s2 / 2), s2 / 2);
return merge(h1, s1, h2, s2);
}

Sort List[leetcode] 由归并排序的递归和循环,到本题的两种解法的更多相关文章

  1. Hadoop基础-HDFS递归列出文件系统-FileStatus与listFiles两种方法

    Hadoop基础-HDFS递归列出文件系统-FileStatus与listFiles两种方法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. fs.listFiles方法,返回Loc ...

  2. LeetCode算法题-Intersection of Two Arrays(Java实现-四种解法)

    这是悦乐书的第207次更新,第219篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第75题(顺位题号是349).给定两个数组,编写一个函数来计算它们的交集.例如: 输入: ...

  3. leetcode-91-解码方法(动态规划和递归两种解法)

    题目描述: 一条包含字母 A-Z 的消息通过以下方式进行了编码: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 给定一个只包含数字的非空字符串,请计算解码方法的总数 ...

  4. LeetCode 42. Trapping Rain Water 【两种解法】(python排序遍历,C++ STL map存索引,时间复杂度O(nlogn))

    LeetCode 42. Trapping Rain Water Python解法 解题思路: 本思路需找到最高点左右遍历,时间复杂度O(nlogn),以下为向左遍历的过程. 将每一个点的高度和索引存 ...

  5. [LeetCode] Validate Binary Search Tree (两种解法)

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  6. Java实现 LeetCode 787 K 站中转内最便宜的航班(两种DP)

    787. K 站中转内最便宜的航班 有 n 个城市通过 m 个航班连接.每个航班都从城市 u 开始,以价格 w 抵达 v. 现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是 ...

  7. LeetCode算法题-Missing Number(Java实现-四种解法)

    这是悦乐书的第200次更新,第209篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第65题(顺位题号是268).给定一个包含n个不同数字的数组,取自0,1,2,...,n ...

  8. LeetCode算法题-Ugly Number(Java实现-四种解法)

    这是悦乐书的第199次更新,第208篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第64题(顺位题号是263).编写一个程序来检查给定的数字是否是一个丑陋的数字.丑陋的数 ...

  9. C#版 - LeetCode 148. Sort List 解题报告(归并排序小结)

    leetcode 148. Sort List 提交网址: https://leetcode.com/problems/sort-list/  Total Accepted: 68702 Total ...

随机推荐

  1. Android ANR发生原因总结

    ANR(Application Not Responding) Android系统中应用无响应 是Android系统中比较常见的问题,当出现ANR时一般情况会弹出一个带有以下文字的对话框提示: Act ...

  2. .NET Remoting 入门实例

    1.创建服务端Class:ProxyServerRemoting using System; using System.Collections.Generic; using System.Text; ...

  3. Python-绑定与未绑定方法通俗讲解

    像函数一样,Python中的类方法也是一种对象.由于既可以通过实例也可以通过类来访问方法,所以在Python里有两种风格:   未绑定的类方法:没有self     通过类来引用方法返回一个未绑定方法 ...

  4. C++的泛型编程方式

    1.使用类模板创建数组 下面这段代码:是创建一个元素为 T 类型的数组. #pragma once template<class T> class MyArray { public: // ...

  5. Current thread must be set to single thread apartment (STA) mode before OLE,当前线程不在单线程单元中,因此无法实例化 ActiveX 控件“8856f961-340a-11d0-a96b-00c04fd705a2”。

    Add the STAThreadAttribute attribute on the Main method. This attribute is required if your program ...

  6. Jumpserver web界面跳板机

    Jumpserver.org 普通用户 仪表盘 查看主机 上传下载 访问官网 欢迎使用Jumpserver开源跳板机系统 帮助 Log out 查看资产 仪表盘 资产管理 查看资产 主机详细信息列表 ...

  7. mybatis开发流程,增删改查

    一.开发流程 1)引jar包 //mybatis_core mybatis3.4core\asm-5.2.jar mybatis3.4core\cglib-.jar mybatis3.4core\co ...

  8. mmcm 和pll

    这个2个有什么区别啊 mmcm 和pll?  1.DCM实际上就是一个DLL,可以对输入时钟进行相位移动,补偿,产生倍频和分频时钟,但是5以及以后的产品不用了.2.PLL相对于DCM,除了不能相移时钟 ...

  9. [na][win]系统优化工具dism++

    系统优化工具, 确实能将c盘扩大个2-3g. 主要是删除日志 优化系统等功能. https://www.chuyu.me/

  10. 使用jquery dialog

    网页开发中,弹窗还是很有必要的.本人比较喜欢jquery ui的dialog. 但是jquery dialog中也有一些略显不方便的,如:没有z-index的参数设置,脚部的按钮样式没办法自定义…… ...