数组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. phpd读取txt文件(自动解析换行)

    <form id="form" method="post" action="whois.php"> <?php $newf ...

  2. replace()替换文字扑获组做法

    var txt = "12312131283", str = txt.replace(/(12(.3))/g,"中文$2");//$1是针对前面的扑获组()的如 ...

  3. efficient c++,单线程内存池

    基于 http://www.cnblogs.com/diegodu/p/4555018.html operator new的知识基础上 介绍这个章节的内容 对于一般直接 new 与delete 性能较 ...

  4. hdu 3859 Inverting Cups

    题意是给出A个杯子,一开始都朝上,每次可以翻B个杯子,问最少需要翻转多少次可以让所有杯子都朝下. 分类讨论: 首先对于A%B==0一类情况,直接输出. 对于A>=3B,让A减到[2B,3B)区间 ...

  5. codeforces #313 div1 A

    捕获一只野生大水题! 首先我们知道边长为L的正三角形含有边长为1的小正三角形为L^2个 那么我们可以通过在六边形的正上,左下,右下补充正三角形使得原图形变成正三角形 然后再将补充的减去即可 #incl ...

  6. QGraphicsEffect介绍(十分漂亮)

    原文链接:Qt 图形特效(Graphics Effect)介绍 QGraphicsEffect也是Qt-4.6引入的一个新功能.它让给图形元素QGraphicsItem增加更佳视觉效果的编程变得非常简 ...

  7. 编程添加"作为服务登录”权利(包括例子和API)

    搜索"log on as a service programmatically" https://msdn.microsoft.com/en-us/library/windows/ ...

  8. Android:时间控件

    1.选择时间TimePicker    监听器:OnTimeChangedListener(obj,int hour,int minute); 常用: 获取时:getCurrentHour(). 获取 ...

  9. SGU 101 AC

    总算AC了,好帅气的算法,同时解决了自环跟非连通,一种自下向上找环的算法过程,这里把欧拉回路讲得很清楚,赞. #include <iostream> #include <vector ...

  10. Android 设置EditText光标位置

    Android中有很多可编辑的弹出框,其中有些是让我们来修改其中的字符,这时光标位置定位在哪里呢? 刚刚解了一个bug是关于这个光标的位置的,似乎Android原生中这种情况是把光标定位到字符串的最前 ...