上代码,本文用了三种方法实现,时间复杂度不一样,空间复杂度都是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. zabbix_get命令不存在

    yum install zabbix-get.x86_64

  2. MPI环境配置

    单机多核配置:https://www.cnblogs.com/shixiangwan/p/6626156.html 多计算机配置:https://blog.csdn.net/WASEFADG/arti ...

  3. js 多张图片加载 环形进度条

    css 部分使用 svg 绘制环形 svg{width:100px; height: 100px; margin:15% auto 25%; box-sizing:border-box; displa ...

  4. P2895 [USACO08FEB]流星雨Meteor Shower

    传送门 预处理出每个位置最早被摧毁的时间,在此之前都可以走 直接dfs加个记忆化和最优性剪枝就好了 一定要注意流星的边界,如果波及到负数坐标的位置不要去考虑会RE 一定要考虑流星砸到边界的情况 如 ( ...

  5. BAPC 2014:Button Bashing(暴力+bfs)

    题意: 给出n,m,代表微波炉有n个按钮,要求达到总时间为m 然后给出n个数,代表n个按钮能增加的时间,问最少几步,能够使得按出的总时间大于等于要求的时间,并且相差最小 输出最小的步数与相差的最小值 ...

  6. EXCEL 导入SQL SERVER 方法

    1.注意:确认是否已安装 AccessDatabaseEngine.exe 2.可视化按提示操作.

  7. java thread start到run:C++源码分析

    转:https://hunterzhao.io/post/2018/06/11/hotspot-explore-inside-java-thread-run/ 整体流程 java new Thread ...

  8. js 中callback函数的定义和使用

    这是js里的解释了,其他语言的算我没说. 字面上理解下来就是,回调就是一个函数的调用过程.那么就从理解这个调用过程开始吧.函数a有一个参数,这个参数是个函数b,当函数a执行完以后执行函数b.那么这个过 ...

  9. 11073 最热门的K个搜索串

    11073 最热门的K个搜索串时间限制:350MS 内存限制:65535K提交次数:0 通过次数:0 题型: 编程题 语言: G++;GCC;VCDescription大家都非常喜欢而习惯用baidu ...

  10. [转]显示农历日期的JS

    本文转自:http://blog.sina.com.cn/s/blog_47377e77010009xc.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD ...