归并排序能够有两种思路----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. windows下ACE安装使用教程(转)

    ACE简介:ACE是一个跨平台的用于并发通信的C++框架.它提供了丰富的C++封装器和框架组件.使用ACE,开发者可以开发出高性能,实时的通信服务和应用.ACE利用进程间通信,事件分离,动态链接和并发 ...

  2. 【Linux】压缩与解压

    一: 下面这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个: tar-c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件 下面的参数是根据需要在 ...

  3. RSA/DSA 密钥的工作原理

    下面从整体上粗略的介绍了 RSA/DSA 密钥的工作原理.让我们从一种假想的情形开始,假定我们想用 RSA 认证允许一台本地的 Linux 工作站(称作 localbox)打开 remotebox 上 ...

  4. Apache James 发送邮件到外网

    在config.xml文件中查找到<dnsserver>然后把默认的<server> 127.0.0.1</server> 改成如下形式:<dnsserver ...

  5. IOS研究之App转让流程须知具体介绍

     网络上有非常多开发人员提问怎么转让App并想知道具体的流程.实际上Appstore的App转让流程还是比較简单的.以下特酷吧依据自己的实际操作总结下iOS Appstore中App的转让流程.供 ...

  6. shell中$0,$?,$!等的特殊使用方法

    变量说明: $$ Shell本身的PID(ProcessID) $! Shell最后执行的后台Process的PID $? 最后执行的命令的结束代码(返回值) $- 使用Set命令设定的Flag一览 ...

  7. 匿名类型 使用泛型T linq返回dynamic类型的匿名实体 如何把匿名类型.GetType()返回的对象传进泛型里面 EF实体查询出的数据List<T>转DataTable出现【DataSet 不支持 System.Nullable<>】的问题

    [100分]紧急求助:LinQ下使用IQueryable<T>如何将返回类型<T>使用匿名类型 问题描述如下:我有一个方法如下:public IQueryable Dissen ...

  8. MQTT 学习笔记

    MQTT特点 MQTT协议是为大量计算能力有限,且工作在低带宽.不可靠的网络的远程传感器和控制设备通讯而设计的协议. 1.使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合 2.对负载内容 ...

  9. Lintcode---实现 Trie

    实现一个 Trie,包含 insert, search, 和 startsWith 这三个方法. 注意事项 你可以假设所有的输入都是小写字母a-z. 您在真实的面试中是否遇到过这个题? Yes 样例 ...

  10. html-loldemo

    百度版lol百科小样 <!DOCTYPE html> <html lang="en"> <head> <title>英雄联盟百科&l ...