编程之美6:数组循环移位

原创 2015年04月13日 16:49:55

楼主又来~(≧▽≦)/~啦啦啦,科研,就是要这么一鼓作气。额,其实楼主的老本行是推公式啊,做这些算法题,其实是楼主在偷懒。额,话不多说了,快请出我们今天的主角吧!还是关于数组的-数组循环移位。

下面我们来看下题目的要求。

题目要求:

设计一个算法,把一个含有N个元素的数组循环右移K位,要求时间复杂度O(N),且只允许使用两个附加变量

题目解答

我们来自己给个例子,来帮助自己思考。如数组为[1, 2, 3, 4, 5, 6, 7, 8],循环移位4次。
原始序列:[1, 2, 3, 4, 5, 6, 7, 8]
右移1位:[8, 1, 2, 3, 4, 5, 6, 7]
右移2位:[7, 8, 1, 2, 3, 4, 5, 6]
右移3位:[6, 7, 8, 1, 2, 3, 4, 5]
右移4位:[5, 6, 7, 8, 1, 2, 3, 4]

解法一:时间复杂度O(N * K)

代码:

#include <iostream>  
#include <vector>


using namespace std;  
void getShiftArray (int *pArray, int len, int K);
void printArray(int *pArray, int len);

int main()  
{  
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
    int len = sizeof(a) / sizeof(int);
    int K = 4;
    getShiftArray(a, len, K);
    printArray(a, len);
    system("pause");
} 


void getShiftArray (int *pArray, int len, int K)
{
    int endTemp = 0;
    while (K--)
    {
        endTemp = pArray[len - 1];           //保存数组最后一个元素
        for (int n = len - 1; n >= 0; n--)
        {
            pArray[n] = pArray[n - 1];
        }
        pArray[0] = endTemp;
    }
}  

void printArray(int *pArray, int len)
{
    for (int i = 0; i < len; i++)
    {
        cout << pArray[i] << " ";
    }
    cout << endl;
}

这种解法是不符合题目的线性复杂度要求的。

但是我们在这儿会意识到一个问题,如果K > N怎么办呢?我们可以试验一下,一个数组循环移位N次,数组会回到原始的样子。那么当K> N时,只需要向右循环移位K - N次就好了。综合一下,无论K取什么值,那么都只需要向右循环移位K % N次,那么上面的代码只需要改动一点点,时间复杂度就可以变为O(NN),虽然还是不符合要求,但是我们看下面的代码:

#include <iostream>  
#include <vector>


using namespace std;  
void getShiftArray (int *pArray, int len, int K);
void printArray(int *pArray, int len);

int main()  
{  
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
    int len = sizeof(a) / sizeof(int);
    int K = 12;
    getShiftArray(a, len, K);
    printArray(a, len);
    system("pause");
} 


void getShiftArray (int *pArray, int len, int K)
{
    int endTemp = 0;

    K = K % len;
    while (K--)
    {
        endTemp = pArray[len - 1];           //保存数组最后一个元素
        for (int n = len - 1; n >= 0; n--)
        {
            pArray[n] = pArray[n - 1];
        }
        pArray[0] = endTemp;
    }
}  

void printArray(int *pArray, int len)
{
    for (int i = 0; i < len; i++)
    {
        cout << pArray[i] << " ";
    }
    cout << endl;
}

解法二:线性时间

其实,细心发现一下就看出来了,[1, 2, 3, 4, 5, 6, 7, 8]可以分为两部分,不加粗的为第一部分,加粗的是第二部分。如果这个数组向右循环移位4次的话,其实两部分的内部顺序都是不变的,只是两个部分交换一下就好了。那么我们可以按照下面的流程来完成循环移位(靠,真是大神,怎么想出来的?)。

原始序列:[1, 2, 3, 4, 5, 6, 7, 8]
半部分逆序:[4, 3, 2, 1, 5, 6, 7, 8]
半部分逆序:[4, 3, 2, 1, 8, 7, 6, 5]
整个序列逆序:[5, 6, 7, 8,1, 2, 3, 4 ]

看代码,是如此的简单。

#include <iostream>  
#include <vector>


using namespace std;  
void getShiftArray (int *pArray, int len, int K);
void printArray(int *pArray, int len);
void reverseArray(int *pArray, int start, int end);

int main()  
{  
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
    int len = sizeof(a) / sizeof(int);
    int K = 12;
    getShiftArray(a, len, K);
    printArray(a, len);
    system("pause");
} 


void getShiftArray (int *pArray, int len, int K)
{

    K = K % len;
    //前半部分逆序
    reverseArray(pArray, 0, len - K - 1);
    //后半部分逆序
    reverseArray(pArray, len - K, len - 1);
    //整个序列逆序
    reverseArray(pArray, 0, len - 1);
}  

void reverseArray(int *pArray, int start, int end)
{
    for (; start < end; start++, end--)
        swap(pArray[start], pArray[end]);
}

void printArray(int *pArray, int len)
{
    for (int i = 0; i < len; i++)
    {
        cout << pArray[i] << " ";
    }
    cout << endl;
}

哈哈哈哈,有没有明白呢?楼主申请专栏去啦!如果你也想学习算法,那么可以和楼主一起抱团啊,多多交流,加油加油↖(^ω^)↗

相关文章推荐

数组循环移位的几种解法

题目描述: 设计一个算法,把一个含有N个元素的数组循环右移K位。解法一: 最容易想到的就是每次将数组中的元素右移一位,循环K次。#include using...

数组循环左移

设将n(n>1)个整数存放到一维数组R中。设计一个在时间和空间两方面尽可能高效的算法。将R中保存的序列循环左移p(0...

数组元素循环左移p个位置

数组A为{x0,x1,x2,x3,x4,x5....,xn-1}循环左移p之后为{xp,xp+1,xp+1,...,xn-1,x0,x1,x2,..xp-1} 思路: 假设数组为{1,2,3,4,...

循环左移数组

【版权声明:转载请保留出处:blog.csdn.net/algorithm_only。邮箱:liuy0711@foxmail.com】 1.        算法要求 设将n(n>1)个整数...

数组循环左移

题: 对于有n个元素的数组 int a[n]={....};写一个高效算法将数组内容循环左移m位 比如: int a[6] ={1,2,3,4,5,6} ,循环左移3位得到结果{456123}, ...

pta 习题集 5-15 数组循环左移

本题要求实现一个对数组进行循环左移的简单函数:一个数组aa中存有nn(>0>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向左移mm(≥0≥0)个位置,即将aa中的数据由(a0a1⋯an−1...
  • Dacc123
  • Dacc123
  • 2017年03月12日 16:27
  • 825

对数组中的元素循环左移(或右移)

题目要求: A为一个包含有n个元素的数组{a0,a1,a2,a3,…,a(p-1),ap,a(p+1)…,a(n-2),a(n-1)},现在将A中的元素循环左移p个单位,得到新的数组B={a(p),a...

程序员面试100题之十一:数组循环移位

设计一个算法,把一个含有N个元素的数组循环右移K位,要求时间复杂度为O(N),且只允许使用两个附加变量。      不合题意的解法如下:      我们先试验简单的办法,可以每次将数组中的元素右移...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

数组循环左移

[提交]   [统计]   [讨论] 题目描述 本题要求实现一个对数组进行循环左移的简单函数:一个数组a中存有n(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向左移m(≥0)个位置,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:编程之美6:数组循环移位
举报原因:
原因补充:

(最多只允许输入30个字)