`
810364804
  • 浏览: 785426 次
文章分类
社区版块
存档分类
最新评论

交换两个子数组的位置(只使用1个辅助空间)

 
阅读更多

一、问题描述

其实这是一个非常基本和常用的数组操作,它的描述如下:

有一数组X[0...n-1],现在把它发为两个子数组x1[0...m]和x2[m+1...n-1],交换这两个子数组,使用数组x由x1x2变成x2x1,例如x={1,2,3,4,5,6,7,8,9},x1={1,2,3,4,5},x2={6,7,8,9},交换后,x={6,7,8,9,1,2,3,4,5}。

二、解题思路

1、蛮力法

第一个想到的办法当然是用new或malloc开辟一个与其中一个子数组(如第一个子数组x1)大小的数组,并把此子数组的内容复杂到新开辟的数组中,然后把第二个数组x2的内容放到数组x的前面,再加新数组的内容(即x1的内容)复制到数组x的后面,所以空间复杂为O(n),要扫描数组2次,即时间复杂度为O(N)

2、平行移动法

这个方法有点类似于字符串的平行移动,这里以向左移动为例,我们可以把数组看成是环形的,每次用一个变量记录数组的第一个元素x[0],把数组的全部元素向左移动一个单位,并把用变量记录的数据(即原先的x[0])放到数组的最后一个位置。如此循环第一个子数组的元素的个数次,即把第一个子数组x1的元素全部移动到后面,就能把两个子数组交换。因为只用到了一个变量保存x[0],所以空间复杂度为O(1),而要把数组中的每个元素都移动第一个子数组的元素的个数次,设原数组的元素个数为N,则时间复杂度为O(N*(x1/x)*N) = O(N^2)。

3、分治法

既然我们不能一次把两个子数组交换,那么就先把分别两个子数组的内容交换,然后把整个数组的内容交换,即可得到问题的解,而交换两个变量的值,只需要使用一个辅助储存空间。其实这个非常好证明,就用上面的例子,自己算一算即可,证明如下:

交换两个数组后,x1={5,4,3,2,1},x2={9,8,7,6},即x={5,4,3,2,1,9,8,7,6}

交换整个数组后,x={6,7,8,9,1,2,3,4,5}

所以,空间复杂度为O(1),扫描了两次数组,时间复杂度为O(n)。

三、代码实现

这里给出了第三种方法的实现代码,考虑到代码的通用性,使用了模板函数,如果看不懂模板函数,则只需要忽略template<typename T>,并把T看作是一个类型即可。代码如下:

template<typename T>
void SwapSubArray(T *array, int array_size, int div);


template<typename T>
void Swap(T *array, int left, int right);


template<typename T>
void SwapSubArray(T *array, int array_size, int div)
{
    //首先交换第一个子数组的内容
    Swap(array, 0, div);
    //再交换第二个子数组的内容
    Swap(array, div+1, array_size-1);
    //交换整个数组的元素
    Swap(array, 0, array_size-1);
}


template<typename T>
void Swap(T *array, int left, int right)
{
    //交换数组left到right的内容
    for(; left < right; ++left, --right)
    {
        T tmp = array[left];
        array[left] = array[right];
        array[right] = tmp;
    }
}
测试代码如下:

#include <iostream>
#include "swap_subarray.h"

using namespace std;

int main()
{
    int a[9] = {1,2,3,4,5,6,7,8,9};
    SwapSubArray(a, 9, 4);
    for(int i = 0; i < 9; ++i)
        cout << a[i];
    return 0;
}
运行结果如下:


分享到:
评论

相关推荐

    计算机二级公共基础知识

    能使用二分法查找的线性表必须满足用顺序存储结构和线性表是有序表两个条件。 “有序”是特指元素按非递减排列,即从小到大排列,但允许相邻元素相等。下一节排序中,有序的含义也是如此。 对于长度为n的有序线性表...

    java异或-Java异或运算总结.pdf

    例⼀:在不引⼊第三个变量的情况下,两个变量的值(整数) //交换a、b的值 例⼆:判断奇数偶数更简单更⾼效的做法 //这个实际考的不多, 太简单 //思路:奇数的⼆进制最低为⼀定为1,偶数的⼆进制最低位⼀定为0, a^...

    大学计算机基础题目第四章

    1、在计算机系统中,外存储器必须通过___C________才能实现与主机的信息交换。 A电缆 B 总线插槽 C接口 D插座 2、CPU中的_____C_________可存放少量数据。 A存储器 B辅助存储器 C寄存器 D只读存储器 3、ROM的特点...

    Java开发技术大全(500个源代码).

    trySwap.java 试图交换两个形参的值 useOnlyTest.java 创建多个对象,演示this的作用 useStaticBolck.java 使用静态块 useStVar.java 使用静态成员变量 第4章 示例描述:本章学习继承与多态。 absClass.java ...

    知名公司数据结构笔试题及答案

    (2)已知两个链表head1 和head2 各自有序,请把它们合并成一个链表 依然有序。 (3)已知两个链表head1 和head2 各自有序,请把它们合并成一个链表 依然有序,这次要求用递归方法进行。 ( Autodesk) 24.编最优化...

    《数据结构 1800题》

    6.数据结构中评价算法的两个重要指标是(时间复杂度和空间复杂度) 【北京理工大学 2001 七、1(2分)】 7. 数据结构是研讨数据的_(1)物理结构_和_(2)逻辑结构 _,以及它们之间的相互关系,并对与这种结构定义...

    第四届 蓝桥杯 竞赛试题题目 C/C++高职高专组

     注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。  注意: 所有依赖的函数必须明确地在源文件中 #include , 不能通过工程设置而省略常用头文件。    提交时,注意选择所期望的...

    精心整理史上最全的数据结构flash演示动画,共5个版本,祝大家考研成功!

    \数据结构flash演示\版本1\5-3-2相邻两个子表之间的关系.swf \数据结构flash演示\版本1\5-3-3广义表.swf \数据结构flash演示\版本1\5-3稀疏矩阵的转置.swf \数据结构flash演示\版本1\5_1_1矩阵按行存储.swf \...

    JAVA上百实例源码以及开源项目

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    JAVA上百实例源码以及开源项目源代码

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    C++MFC教程

    1、消息的组成:一个消息由一个消息名称(UINT),和两个参数(WPARAM,LPARAM)。当用户进行了输入或是窗口的状态发生改变时系统都会发送消息到某一个窗口。例如当菜单转中之后会有WM_COMMAND消息发送,WPARAM的高...

    C++标准程序库STL的架构

    7.3.3 iter_swap()交换两个迭代器所指内容 68 7.4 迭代器配接器(adapter) 69 7.4.1 逆向迭代器 69 7.4.2 Insert迭代器 72 7.4.3 Stream迭代器 75 7.5 迭代器特性 76 8 STL仿函数 77 8.1 仿函数概念 77 8.1.1 仿函数...

    LINUX操作系统(电子教案,参考答案)

    本章主要介绍在Linux上比较常用的两个proxy服务器软件的配置。 本书最后还附有参考答案,以供读者对照课后习题进行练习。 四、本书适用对象 本书适合用于大专院校、电脑培训班等作为Linux或UNIX操作系统课程的教材,...

    leetcode答案-LeetCode:个人LeetCode题解,用图片的形式展示解题思路

    leetcode 答案 个人 LeetCode 题解,用图片的形式展示解题思路。...:比较得到两个数组最大的元素,作为最大值放在最后。 :将后面的偶数跟前面的奇数交换。标签:前后双指针 三指针 :先排序,3 数之和转换为 2

    leetcode296-leetcode-in-py-and-go:Go中的Leetcode

    29:除以两个整数:溢出; 两反 31:下一个排列:再做一次(排序!) 32:最长有效(),使用栈,左推idx 33: search-in-rotated-sorted-array ,比较中间值和边,而不是目标和边 40:combination-sum-ii:传递最后...

    Delphi5开发人员指南

    4.5.4 子窗体TChildForm 94 4.5.5 数据库基础模式窗体TDBMode- Form 96 4.5.6 数据库导航/状态窗体TDBNavstat- Form 97 4.5.7 使用框架进行应用程序结构 设计 102 4.6 一些项目管理的功能 103 4.6.1 在项目中添加...

Global site tag (gtag.js) - Google Analytics