zoukankan      html  css  js  c++  java
  • 旋转阵列

    称号:有n整数,所以在每一个向后移动的序列号m个位置,最后m个数变成最前面m个数。写一函数实现以上功能。在主函数中输入n个整数和输出调整后的n个数。

    要求:最多仅仅让使用一个暂时空间。

    函数接口定义例如以下:

    Int moveRight_n(int*  p,int  n,int  m);

    这道题最easy想到的方法就是循环移位,实现例如以下:

    int moveRight_n(int* p, int n, int m)
    {
    	int nRet = 0;
    	int* pStart = NULL;
    	int* pEnd = NULL;
    	int nTmp;
    
    	if (p == NULL || n <= 0 || m < 0)
    	{
    		nRet = -1;
    		printf("param input error!
    ");
    		return nRet;
    	}
    
    	if (m > n)
    		m %= n;
    
    	int i, j;
    	for (i = 0; i<m; ++i)
    	{
    		nTmp = p[0];
    		for (j = n - 1; j>0; --j)
    		{
    			if (j + 1 == n)
    				p[(j + 1) % n] = p[j];
    			p[j + 1] = p[j];
    		}
    		p[j + 1] = nTmp;
    	}
    
    	return nRet;
    }


    PS:使前面各数顺序向后移m个位置,注意题意了,这里不是旋转数组。前面各数顺序向后移m个位置是不可以使用旋转数组的高效算法的。

    所以以下的内容不适合本题意思。

    还是太粗心了!

    这样的方法效率低,可是是最主要的解法。我们还能够观察数组移动的规律,里面的每个数字不管向左还是向右移动n位,都会回到原来的位置。而我们传入的m值可能大于n值,所以这段代码也就是处理这样的情况

    if(m > n)

    m %= n;

    我们右移m位相当于左移n-m位,利用这个我们还能够近一半提高上面基本算法的效率。我们先求出数组长度的一半mid,假设m>mid

    题目要求左移m位。我们能够右移n-m位。这样能够降低循环的次数,从而提高了一些效率。

    最高效的时间复杂度当然是O(n),类似于july博客《程序猿编程艺术》的旋转字符串一节。把数组分为【0...m】和【m+1,n2部分,分别对这2段数组反转,然后对整个数组反转,最后就是所要求得的移位后的数组。

    具体算法解说參见july的博客《程序猿编程艺术》第一章、左旋转字符串,里面有具体的解说,在这里也向july大神致敬。

    以下是实间复杂度为O(n)的算法实现:

    void Swap(int* p1, int *p2)
    {
    	int nTmp;
    	nTmp = *p1;
    	*p1 = *p2;
    	*p2 = nTmp;
    }
    
    int moveRight_n(int* p, int n, int m)
    {
    	int nRet = 0;
    	int* pStart = NULL;
    	int* pEnd = NULL;
    
    	if (p == NULL || n <= 0 || m < 0)
    	{
    		nRet = -1;
    		printf("param input error!
    ");
    		return nRet;
    	}
    
    	if (m > n)
    		m %= n;
    
    	pStart = p;
    	pEnd = p + n - m - 1;
    	while (pStart < pEnd)
    	{
    		Swap(pStart, pEnd);
    		++pStart;
    		--pEnd;
    	}
    	
    	pStart = p + n - m;
    	pEnd = p + n - 1;
    
    	while (pStart < pEnd)
    	{
    		Swap(pStart, pEnd);
    		++pStart;
    		--pEnd;
    	}
    
    	pStart = p;
    	pEnd = p + n - 1;
    
    	while (pStart < pEnd)
    	{
    		Swap(pStart, pEnd);
    		++pStart;
    		--pEnd;
    	}
    
    	return nRet;
    }
    
    


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    分布式与集群的区别是什么?
    Java NIO:IO与NIO的区别 JAVA BIO与NIO、AIO的区别
    localStorage使用总结 JS 详解 Cookie、 LocalStorage 与 SessionStorage
    tomcat+nginx+redis实现均衡负载、session共享 存储过程的优缺点 HTTP、TCP、IP协议常见面试题
    高并发下的Java数据结构(List、Set、Map)
    [剑指offer] 31. 整数中1出现的次数(从1到n整数中1出现的次数)
    [剑指offer] 30. 连续子数组的最大和
    [剑指offer] 29. 最小的K个数
    [剑指offer] 28. 数组中出现次数超过一半的数字
    [leetcode] 51. N-Queens (递归)
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4750320.html
Copyright © 2011-2022 走看看