数组al[0,mid-1] 和 al[mid,num-1],都分别有序。将其merge成有序数组al[0,num-1],要求空间复杂度O(1)

思路:一般的归并是需要O(n)的空间,而这里要求空间复杂度为O(1),也就是只能使用常熟级别的临时变量。而原地操作无非就是移动,关键是怎么移动。在编程珠玑中有一个旋转算法(旋转后k个元素到前面),可以在这里起到关键性作用。见http://www.cnblogs.com/ivorfeng/archive/2013/05/12/3074822.html

因为数组al[0,mid-1] 和 al[mid,num-1],都分别有序,我们要做的是将较小的元素(可能是连续的一片)插入到合理的位置中;不妨假设left 和right是两个有序数组中的下标,a[left] < a[right],首先要在左半部分找到第一个比a[right]大的下标newleft,接着在右半部分找到比a[newleft]小的下表newright,并记录right到newright所移动的步数move

如上图所示,最后就是将红色框中的元素进行右旋转move(这里为3)个元素。

代码如下:

 //翻转数组
template <typename T>
void Reverse(T *a, int size)
{
T tmp;
for(int i = ; i < size/; ++i)
{
tmp = a[i];
a[i] = a[size - i - ];
a[size - i - ] = tmp;
} }
//旋转
template <typename T>
void Rotate(T*a, int size, int pos)
{
Reverse(a, pos);
Reverse(a + pos, size - pos);
Reverse(a, size); }
template<typename T>
void InplaceMerge(T *a, int size, int mid)
{
int fir = ;
int sec = mid;
int Move = ;
while (fir < sec && sec < size)
{
while (fir < sec && a[fir] < a[sec])
{
++fir;
}
Move = ;
while ( sec < size && a[sec] < a[fir])
{
++sec;
++Move;
}
Rotate(a + fir, sec - fir, sec - fir - Move);
fir += Move;
}
}

这样空间复杂度主要是Reverse中用到,为O(1).

In place Merge(原地归并)的更多相关文章

  1. [leetcode]56. Merge Intervals归并区间

    Given a collection of intervals, merge all overlapping intervals. Example 1: Input: [[1,3],[2,6],[8, ...

  2. 【原创】Algorithms:原地归并排序

    第一次归并: a[0] a[1] a[2] a[3] a[4] a[5] a[6] 23 8 19 33 15 6 27 ↑             ↑ i     j 最开始i指向a[0],j指向a ...

  3. 归并排序Java实现

    package practice; import edu.princeton.cs.algs4.*; /* * 归并排序 * 时间复杂度O(NlgN) N为数组长度 * 归并排序在小数组上表现并不好可 ...

  4. 算法(第四版)C# 习题题解——2.2

    写在前面 整个项目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp 查找更为方便的版本见:http ...

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

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

  6. 各种排序算法的总结、比较与Java实现

    1 快速排序(QuickSort) 快速排序是一个就地排序,分而治之,大规模递归的算法.从本质上来说,它是归并排序的就地版本.快速排序可以由下面四步组成. (1) 如果不多于1个数据,直接返回.(2) ...

  7. 选择排序、快速排序、归并排序、堆排序、快速排序实现及Sort()函数使用

    1.问题来源 在刷题是遇到字符串相关问题中使用 strcmp()函数. 在函数比较过程中有使用 排序函数 Sort(beg,end,comp),其中comp这一项理解不是很彻底. #include & ...

  8. 数据结构和算法(Golang实现)(23)排序算法-归并排序

    归并排序 归并排序是一种分治策略的排序算法.它是一种比较特殊的排序算法,通过递归地先使每个子序列有序,再将两个有序的序列进行合并成一个有序的序列. 归并排序首先由著名的现代计算机之父John_von_ ...

  9. 《算法 (第4版)》【PDF】下载

    <算法 (第4版)>[PDF]下载链接: https://u253469.ctfile.com/fs/253469-231196349 (第4版)>[PDF]"  TITL ...

随机推荐

  1. Java NIO(New I/O)的三个属性position、limit、capacity

    Java NIO(New I/O)的三个属性position.limit.capacity 在缓冲区中,最重要的属性有下面三个,它们一起合作完成对缓冲区内部状态的变化跟踪: capacity posi ...

  2. Buffer

    Buffer 我们用原有 IO 读写文件应该不会陌生了,顺带回顾一下,大致两种: 1. 在 InputStream 或 OutputStream 上读写字节或字节数组,读 InputStream 时用 ...

  3. 在Oracle SQL Developer中创建新连接

    步骤: 1.如下图 2.点击“测试”,如果左下角的状态出现“成功”,说明OK

  4. Tornado,了解一下

    多了解不一样的PYTHON框架,对深入了解DJANGO,总是有帮助的. import textwrap import tornado.httpserver import tornado.ioloop ...

  5. HDU4647+贪心

    /* 贪心. 题意:给定一些点 一些边 点和边都有价值.现在A B 选点.求A-B的maxVal 思路:分割边.边的1/2分给两个端点. 如果这两个点被同一个人取,则ok:否则 做减法也行,对题意无影 ...

  6. Web Api 入门

    http://www.cnblogs.com/developersupport/p/WebAPI-Security.html http://www.cnblogs.com/r01cn/archive/ ...

  7. 李洪强iOS开发之 - WebViewJavascriptBridge

    李洪强iOS开发之 - WebViewJavascriptBridge 01 - JS端:   02 - iOS端 01 遵守代理协议 02 申明属性 03 开启日志 04 给哪个webview建立J ...

  8. PHP基础语法3

    文件系统 判断文件是否存在 如果只是判断文件存在,使用file_exists就行,file_exists不仅可以判断文件是否存在,同时也可以判断目录是否存在,从函数名可以看出, is_file是确切的 ...

  9. Centos系统备份与恢复教程

    Linux不像windows,它不限制根用户存取任何东西,因此,你完全可以把一个分区上每一个的文件放入一个TAR文件中. 使用root用户切换到根目录 然后,使用下面的命令备份完整的系统: tar c ...

  10. MYSQL 优化建议

    转自 http://coolshell.cn/articles/1846.html MYSQL 优化建议20条 1. 为查询缓存优化你的查询 大多数的MySQL服务器都开启了查询缓存.这是提高性最有效 ...