数组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. hibernate中session

    hibernate中的session是一级缓存,可以理解为进程级的缓存.在进程运行期间一直存在. session可以理解为一个可以操作数据库的对象 具体如何操作数据库? session中有方法, 如果 ...

  2. CSU1326+背包+并查集

    先预处理出有多少个任务即可 #include<stdio.h> #include<stdlib.h> #include<string.h> #include< ...

  3. QGraphicsEffect介绍(十分漂亮)

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

  4. FocusWriter

    2. FocusWriter 如果你正在从事某种写作——小说.博客.文档等——你绝对希望认识一下FocusWriter.它已经有近十年的发布历史了,但是一直是我们最喜欢的无分心写作应用之一.如果你希望 ...

  5. QTreeView只显示指定驱动器及其目录,隐藏所有兄弟节点

    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setup ...

  6. 190. Reverse Bits

    题目: Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented ...

  7. 绕过图片格式限制上传木马获取WebShell

    思路: 图片上传功能中,前端页面上传的是.png格式的图片文件,但是抓包Request中修改图片后缀为.php 可以绕过对上传文件格式的限制,文件的上传路径可以在上传后的页面或查看上传成功后的resp ...

  8. &&运算符和||运算符的优先级问题

    package priority; public class TestAndOrPriority { /* * &&的优先级高就不代表 他会先运行 ||的右边 而是说会把右边用& ...

  9. 关于C的一些理解

    关于字符数组和字符指针 关于相互赋值问题一只有疑问,其实是自己搞不清指针和地址的关系.地址可以指向一块内存但是不一定存在于内存,比如字符数组名,数组名是地址,但是不实际存在于内存中,无法修改,而字符指 ...

  10. while ((ch = getchar()) != EOF)中ch定义为char还是int型?cin、scanf等如何结束键盘输入

    2013-07-09 18:55:42 EOF是文件的结束符,具体可以作为文本文件的结束符,也可以作为键盘输入char类型数据时的结束符.对于不同的系统,EOF的定义可能不同,一般定义为-1.因为ch ...