关闭

编程之美---数组循环移位

标签: 编程之美
236人阅读 评论(0) 收藏 举报
分类:

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

解法一:

简单的办法是,每次将数组中的元素右移一位,循环K次。abcd1234 -> 4abcd123 -> 34abcd12。

代码如下:

public static void rightShift(int[] array, int len, int k){
        while(k > 0){
            int temp = array[len-1];
            for(int i = len-1; i > 0; i--){
                array[i] = array[i-1];
            }
            array[0] = temp;
            k--;
        }
    }

算法的时间复杂度为 O(K*N)。
当K是一个远大于N的数时,上面的解法就需要改进了。当 k=50000000时,移位所需要的时间如下:
这里写图片描述

解法二:

观察循环右移的特点后,发现每个元素右移N位后,都会回到原来的位置,因此右移 K 位跟右移 k%N 位的结果是一样的,算法改进如下:

public static void rightShift(int[] array, int len, int k){
        k %= len;
        while(k > 0){
            int temp = array[len-1];
            for(int i = len-1; i > 0; i--){
                array[i] = array[i-1];
            }
            array[0] = temp;
            k--;
        }
    }

解法三:

假设原数组为12345678,循环右移4位后变为56781234。其中 5678 和 1234的顺序是不变的,可以将这两段当做整体,右移K位就是将这两段的顺序交换。

  1. 逆序排列 1234: 12345678 -> 43215678
  2. 逆序排列 5678: 43215678 -> 43218765;
  3. 整体逆序: 43218765 -> 56781234。

代码如下:

public static void reverse(int[] array, int start, int end){
        for(; start < end; start++, end--){
            int temp = array[end];
            array[end] = array[start];
            array[start] = temp;
        }
    }

    public static void rightShift(int[] array, int len, int k){
        k %= len;
        reverse(array, 0, len-k-1);
        reverse(array, len-k, len-1);
        reverse(array, 0, len-1);
    }

当k=50000000时,所花时间如下:
这里写图片描述

可以看到效率有了明显提升。

0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

编程之美2.18—数组分割

题目: 有一个没有排序,元素个数为2N的正整数数组。要求把它分割为元素个数为N的两个数组,并使两个子数组的和最接近。 基本思想: 假设数组A[1..2N]所有元素的和是SUM。模仿动态规划解0-1背包问题的策略,令S(k, i)表示前k个元素中任意i个元素的和的集合。 显然: ...
  • wtyvhreal
  • wtyvhreal
  • 2015-04-28 11:37
  • 681

编程之美3.1 字符串移位包含问题

这道题目的意思是给定一个字符串,作为源字符串,之后给出其他的字符串,确定源字符串是否能够经过旋转而得到给定的字符串,即移位包含问题。      假如,给定一个字符串 abcdefg,接着给定字符串 cdefgab,很显然,给定的字符串是可以经过源字符串旋转而得到的,但是...
  • DLUTBruceZhang
  • DLUTBruceZhang
  • 2014-10-17 19:02
  • 1256

java编程之美(一)

实践编程已经有足足6年多时间,也算是有一定经验,经常在工作中遇到各种让人不爽的代码编写方式,今天忍不住要来唠叨下。 为什么叫编程之美? 在我看来,代码有丑陋难看和赏心悦目两类,当然还有介于两者之间的。优秀开源框架的源码,让人看了就觉得舒服;而有些新手写的代码,让人看了别扭、添堵。本人也是从新手...
  • tang9140
  • tang9140
  • 2015-11-01 18:28
  • 1040

编程之美-字符串移位包含的问题

第三章 3.1 字符串移位包含的问题问题详细描述:  给定两个字符串s1和s2,要求判断s2是否能够被s1做循环移位得到的字符串包含。输入输出示例:  给定s1=”AABCD”和s2=”CDAA”,返回true;  给定s1=”ABCD”和s2=”ACBD”,返回false。   对于编程之美中使...
  • yannanying
  • yannanying
  • 2015-08-27 21:13
  • 735

编程之美之扩展问题

参考链接:http://blog.csdn.net/wuyuegb2312/article/details/9896831 1.1 让CPU占用率曲线听你指挥 参考: http://blog.csdn.net/wesweeky/article/details/6402564 http://www...
  • jerryzcx
  • jerryzcx
  • 2014-03-06 23:33
  • 2522

2014-04-19编程之美初赛题目及答案解析

第一题: 描述 一般来说,我们采用针孔相机模型,也就是认为它用到的是小孔成像原理。 在相机坐标系下,一般来说,我们用到的单位长度,不是“米”这样的国际单位,而是相邻像素的长度。而焦距在相机坐标系中的大小,是在图像处理领域的一个非常重要的物理量。 假设我们已经根据相机参数,得到...
  • kunlong0909
  • kunlong0909
  • 2014-04-19 16:44
  • 4460

[编程之美-10]面试当中的智力题(不定期更新)

[版权说明]  编程之美系列算法题集参考:  左程云 著《程序员代码面试指南IT名企算法与数据结构题目最优解》  July 著《编程之法面试和算法心得》  何海涛 著《剑指offer》  微软编程之美小组 著《编程之美》  部分题目摘选PA...
  • caicaiatnbu
  • caicaiatnbu
  • 2017-06-07 23:44
  • 393

《编程之美》学习笔记——指挥CPU占用率

问题: 写一个程序,让用户来决定Windows任务管理器(Task Manager)的CPU占用率(单核)。有以下几种情况: 1.CPU占用率固定在50%,为一条直线 2.CPU的占用率为一条直线,具体占用率由命令行参数决定(范围1~100) 3.CPU的占用率状态为一条正弦曲线 4.多核处理器情况...
  • lyh03601
  • lyh03601
  • 2014-09-28 15:07
  • 1170

《编程之美》- 3.3 - 计算字符串相似度 即 最小编辑距离问题

题目 3.3计算字符串的相似度 许多程序会大量使用字符串,对于不同的字符串,我们希望能够有办法判断其相似程度。定义下列操作方法使得两个不同的字符串变得相同: 修改一个字符(如把‘a’改为‘b’)增加一个字符(如把‘abdd’变为‘aebdd’)删除一个字符(如把‘travelling’...
  • fly_yr
  • fly_yr
  • 2016-05-24 20:07
  • 715

编程之美2.21 只考加法的面试题

题目: 我们知道:1+2=3;              4+5=9;         ...
  • huahuahailang
  • huahuahailang
  • 2013-04-16 15:26
  • 3480
    个人资料
    • 访问:23311次
    • 积分:556
    • 等级:
    • 排名:千里之外
    • 原创:28篇
    • 转载:3篇
    • 译文:5篇
    • 评论:4条
    博客专栏
    最新评论