上代码,本文用了三种方法实现,时间复杂度不一样,空间复杂度都是o(1):

public class ArrayKMove {

    /**
* 问题:数组的向左k平移,k小于数组长度
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub ArrayKMove kmove = new ArrayKMove();
kmove.methodOne();
kmove.methodTwo();
kmove.methodThree();
} private static final int i = 10000;
private static final int testNum = 1000;
private int a[];
private long startTime = 0, timeSpan = 0; public ArrayKMove() {
a = new int[i];
for (int j = 0; j < i; j++) {
a[j] = j;
}
} public void printArray() {
for (int j = 0; j < i; j++) {
System.out.println(a[j]);
}
} public void methodOne() {
this.startTime = System.currentTimeMillis();
for (int k = 1; k <= testNum; k++) {
for (int j = 0; j < k; j++) {
this.moveArrayFirstToLast();
}
}
this.timeSpan = System.currentTimeMillis() - this.startTime;
System.out.println("第一种方法消耗时间:" + timeSpan + "毫秒");
} public void moveArrayFirstToLast() {
int m = a[0];
for (int j = 1; j < i; j++) {
a[j - 1] = a[j];
}
a[i - 1] = m;
} public void methodTwo() {
this.startTime = System.currentTimeMillis();
for (int j = 1; j <= testNum; j++) {
this.swapArray(1, j);
this.swapArray(j + 1, i);
this.swapArray(1, i);
}
this.timeSpan = System.currentTimeMillis() - this.startTime;
System.out.println("第二种方法消耗时间:" + timeSpan + "毫秒");
} public void swapArray(int start, int end) {
for (int s = start - 1, e = end - 1; s < e; s++, e--) {
int temp = a[s];
a[s] = a[e];
a[e] = temp;
}
} public int gcdTwoInt(int m, int n) {
if (m <= 0 && n <= 0)
return 0;
if (m <= 0 || n <= 0)
return m <= 0 ? n : m;
int g;
while (n > 0) {
g = m % n;
m = n;
n = g;
}
return m;
} public void moveByGCD(int k) {
if (k <= 0)
return;
int m = this.gcdTwoInt(k, i);
for (int j = 0; j < m; j++) {
int c = a[j];
int p;
for (p = (j + k) % i; p != j; p = (p + k) % i) {
a[(p - k + i) % i] = a[p];
}
a[(p - k + i) % i] = c;
}
} public void methodThree() {
this.startTime = System.currentTimeMillis();
for (int j = 1; j <= testNum; j++) {
this.moveByGCD(j);
}
this.timeSpan = System.currentTimeMillis() - this.startTime;
System.out.println("第三种方法消耗时间:" + this.timeSpan + "毫秒");
}
}

方法一:基本方法,每次左移一位,移动k次即可,但是时间复杂度是o(kn),这个方法可以用牺牲空间复杂度来提升时间效率,即用一个数组保存要平移的k个数据,把原数组直接平移k位后,再把k位数据直接插在后面k个位置即可,时间复杂度o(n)

方法二:先把前k位翻转,再把后面的n-k位翻转,然后整体翻转,这个画图可以证明。

方法三:不是很好理解,基本思路就是,循环替换,用i+k的值替换i处的值,但是是循环,也就是不能数组越界,还有就是要分m条路线,m是n和k的最大公约数。

测试规模:

数组大小10000,

测试次数1000,

每次平移的位数依次为1-1000次;

测试结果:

第一种方法消耗时间:5364毫秒

第二种方法消耗时间:21毫秒

第三种方法消耗时间:129毫秒

结果分析:

三种方法空间复杂度都是o(1)

时间复杂度依次为o(kn)、o(3n)、o(n)

但是测试时间第三种方法消耗的时间却比第二种大,原因是第三种方法中有求解两个最大公约数的操作,而且有运算较为复杂的求余运算,所以消耗时间增加,方法二中只有交换赋值的操作,比较简单。

数组k平移三种方法(java)的更多相关文章

  1. 【JS】JS数组添加元素的三种方法

    1.push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度. 1).语法: arrayObject.push(newelement1,newelement2,....,newelement ...

  2. js数组去重的三种方法

    <script type="text/javascript"> /*// 第一种冒泡法删除 var arr=[1,2,2,78,3,456,456]; for(var ...

  3. 数组去重的三种方法及from方法

    直接上代码: var str="adbbckddwerivka"; var arr=str.split(""); console.log(arr); //ind ...

  4. js 数组去重的三种方法(unique)

    方法一: Array.prototype.unique=function(){ var arr=[];//新建一个临时数组 for(var i=0;i<this.length;i++){//遍历 ...

  5. perl 判断数组相等的三种方法

    1.数组相等,数组成员相同,位置也相同 一般的如果判断@array1 等于 @array2 a.数组长度相同 $#array1=$#array2, 比较数组长度,不能使用length函数,length ...

  6. 数组去重的三种方法 es6

    [1,2,3,4,5,6,7,8,9,2,2,3,3,4,1].filter(function(el,index,arr){ return (index === arr.indexOf(el)); } ...

  7. Java中获取键盘输入值的三种方法

    Java中获取键盘输入值的三种方法     Java程序开发过程中,需要从键盘获取输入值是常有的事,但Java它偏偏就没有像c语言给我们提供的scanf(),C++给我们提供的cin()获取键盘输入值 ...

  8. java数组中的三种排序方法中的冒泡排序方法

    我记得我大学学java的时候,怎么就是搞不明白这三种排序方法,也一直不会,现在我有发过来学习下这三种方法并记录下来. 首先说说冒泡排序方法:冒泡排序方法就是把数组中的每一个元素进行比较,如果第i个元素 ...

  9. (PASS)JAVA数组去重 三种方法 (不用集合)

    第一种方法(只学到数组的看): 定义一个新的数组长度和旧数组的长度一样,存储除去重复数据的旧数组的数据和0, package demo01; import java.sql.Array; import ...

随机推荐

  1. opencv-Haar特征

    特征,判决,得到判决 1.什么是haar特征? 特征 = 某个区域的像素点经过某种四则运算之后得到的结果. 这个结果可以是一个具体的值也可以是一个向量,矩阵,多维.实际上就是矩阵运算 2.如何利用特征 ...

  2. nginx的使用(启动、重启、关闭)

    1. 首先利用配置文件启动nginx. 命令: nginx -c /usr/local/nginx/conf/nginx.conf 重启服务: service nginx restart 2. 快速停 ...

  3. 洛谷2015(树形dp)

    要点 是树形的考虑dfs 分为取一枝,取两枝两种情况,将它们的合法情况进行暴举取最好答案即可,貌似我乱搞得相当冗-- 顺手记忆化 正解应该是树上背包 #include <cstdio> # ...

  4. 1972 HH的项链

    传送门 主席树解法设las[ i ]表示数列中第 i 个数的值 上一次出现的位置,num[ i ]为原数列中第 i 个数的值1. 把 从第 1 到第 i 个数的 las 的值  的出现次数 建立一个线 ...

  5. 2015苏州大学ACM-ICPC集训队选拔赛(2)1002

    草爷要的雷 Problem Description 扫雷一直是风靡实验室的重要娱乐游戏,在赛前赛后.刷题疲惫的时候,扫一局雷经常可以让队员们感受到身心的振奋,毕竟,劳逸结合刷题,防猝死才是硬道理.但是 ...

  6. photoshop特效字体

    一.3D效果字 3D效果文字给人以纵伸感.立体感和真实感,是商家常用到的一种宣传文字.虽然Photoshop软件是平面软件,但是在制作3D效果文字时却游刃有余. 3D效果字的制作可分以下三步完成. 输 ...

  7. js 实现继承的几种方式

    //js中实现继承的几种方式 //实现继承首先要有一个父类,先创造一个动物的父类 function Animal(name){ this.name = name; this.shoot = funct ...

  8. 配置MapReduce程序运行环境

    已安装eclipse,hadoop 查看教程dblab.xmu.edu.cn/blog/hadoop-build-project-using-eclipse/

  9. C# 反射(Reflection)

    反射主要用于在程序运行期间动态解析相关类的类名,命名空间,属性,方法并进行相应操作,以下通过两个简单的例子进行了说明: 示例1:调用程序集内部方法,运行时动态获取相关类的信息,包括类名,命名空间等信息 ...

  10. Hibernate通过自编写sql查询

    public List<InterProductMsg> selectIsHaveProductid(String productId) { String sql="SELECT ...