题目描述
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。

示例 1:

输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]

示例 2:

输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
解释:
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]

说明:

  • 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
  • 要求使用空间复杂度为 O(1) 的原地算法。

我的思路

  1. 一次到位,移动k个位置
  2. 一次移动一个位置,循环k次

两种思路乘以移动方向:左移、右移,共四种结题思路。
举例:一次到位右移k次(PS:空间复杂度不符合要求…)

public void rotate(int[] nums, int k) {if(nums == null || nums.length==1 || k%nums.length==0) {return;}k=k%nums.length;int curVal=nums[0],nextVal=0,curIdx=0,nextIdx=0,count=0;Set<Integer> set = new HashSet<Integer>();set.add(0);while(count++<nums.length) {nextIdx = (curIdx+k)%nums.length;nextVal = nums[nextIdx];nums[nextIdx] = curVal;if(set.contains(nextIdx)) {//防止出现n%k==0时的死循环现象for(int i=1;i<nums.length;i++) {if(!set.contains(i)) {curVal = nums[i];curIdx = i;set.add(curIdx);break;}}}else {curVal = nextVal;curIdx = nextIdx;set.add(curIdx);}}}

思路2: 一次移动一个位置,循环k次

这个思路实现起来最简单,但是相应的时间复杂度也较高(O(k*n))

/*** 双重循环* 时间复杂度O(k*n)* 空间复杂度O(1)*/
public void rotate(int[] nums, int k) {if(nums == null || nums.length==1 || k%nums.length==0) {return;}k=k%nums.length;int len = nums.length;int temp=0;for(int i=0;i<k;i++) {temp= nums[len-1];for(int j=len-1;j>0;j--) {nums[j] = nums[j-1];}nums[0] = temp;}}

拓展后:

思路3:翻转数组

 /*** 翻转* 时间复杂度:O(n)* 空间复杂度:O(1)*/
public void rotate(int[] nums, int k) {if(nums == null || nums.length==1 || k%nums.length==0) {return;}int n = nums.length;k %= n;reverse(nums, 0, nums.length-1);reverse(nums, 0, k-1);reverse(nums, k, nums.length-1);}private void reverse(int[]nums, int start, int end) {int temp=0;while(start<end) {temp=nums[start];nums[start++]=nums[end];nums[end--]=temp;}}

网上大神的代码,摘录如下:

/*** 双重循环* 时间复杂度:O(kn)* 空间复杂度:O(1)*/public void rotate_1(int[] nums, int k) {int n = nums.length;k %= n;for (int i = 0; i < k; i++) {int temp = nums[n - 1];for (int j = n - 1; j > 0; j--) {nums[j] = nums[j - 1];}nums[0] = temp;}}/*** 翻转* 时间复杂度:O(n)* 空间复杂度:O(1)*/public void rotate_2(int[] nums, int k) {int n = nums.length;k %= n;reverse(nums, 0, n - 1);reverse(nums, 0, k - 1);reverse(nums, k, n - 1);}private void reverse(int[] nums, int start, int end) {while (start < end) {int temp = nums[start];nums[start++] = nums[end];nums[end--] = temp;}}/*** 循环交换* 时间复杂度:O(n^2/k)* 空间复杂度:O(1)*/public void rotate_3(int[] nums, int k) {int n = nums.length;k %= n;// 第一次交换完毕后,前 k 位数字位置正确,后 n-k 位数字中最后 k 位数字顺序错误,继续交换for (int start = 0; start < nums.length && k != 0; n -= k, start += k, k %= n) {for (int i = 0; i < k; i++) {swap(nums, start + i, nums.length - k + i);}}}/*** 递归交换* 时间复杂度:O(n^2/k)* 空间复杂度:O(1)*/public void rotate(int[] nums, int k) {// 原理同上recursiveSwap(nums, k, 0, nums.length);}private void recursiveSwap(int[] nums, int k, int start, int length) {k %= length;if (k != 0) {for (int i = 0; i < k; i++) {swap(nums, start + i, nums.length - k + i);}recursiveSwap(nums, k, start + k, length - k);}}private void swap(int[] nums, int i, int j) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}

2019-03-09-算法-进化(旋转数组)相关推荐

  1. leetcode初级算法2.旋转数组

    leecode初级算法2.旋转数组 仅为个人刷题记录,不提供解题思路 题解与收获 我自己的解法: public static void rotate(int[] nums, int k) {int m ...

  2. 【算法】旋转数组【LeetCode】

    一.题目 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 二.示例 示例 1:输入: [1,2,3,4,5,6,7] 和 k = 3 输出: [5,6,7,1,2,3,4] 解 ...

  3. leetcode算法题--旋转数组的最小数字

    原题链接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/ 二分法 int minArray(ve ...

  4. Java算法之旋转数组

    189 class Solution {public void rotate(int[] nums, int k) {int len = nums.length;int[] tmps = new in ...

  5. leetcode旋转数组 c语言,leetcode explore 初级算法第三题,旋转数组代码实现

    leetcode explore 初级算法第三题,旋转数组代码实现.原题链接: 题目分析 因为题目不是很长,这里把题目贴出来: 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. ...

  6. 程序员面试题精选100题(42)-旋转数组的最小元素[算法]

    题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个排好序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的 ...

  7. 算法练习day20——190411(重建二叉树、斐波那契数列、跳台阶、矩形覆盖、变态跳台阶、旋转数组的最小数字、矩阵中的路径)

    1.重建二叉树 根据二叉树的前序遍历和中序遍历的结果,重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. preorder = [3,9,20,15,7].inorder = [9 ...

  8. Python3实现旋转数组的3种算法

    下面是Python3实现的旋转数组的3种算法. 一.题目 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 例如: 输入: [1,2,3,4,5,6,7] 和 k = 3 输出: ...

  9. 数据结构与算法--查找与排序另类用法-旋转数组中的最小数字

    查找与排序 查找 查找与排序都在程序设计中常被用到的算法.查找相对而言简单,一般都是顺序查找,二分查找,哈希表查找,和二叉排序树查找.其中二分查找是我必须熟悉的一种. 哈希表和二叉排序树主要点在于他的 ...

  10. 算法题解:旋转数组的最小数字

    题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 解题思路 将旋转数组对半分可以得到一个包含最小元素的新旋转数组 ...

最新文章

  1. 为什么正则化可以起到对模型容量进行控制_正则化为什么能防止过拟合(重点地方标红了)...
  2. VMware中Red Hat Enterprise Linux 7 配置桥接模式局域网
  3. JSON转换工具---jackson
  4. python标注工具_Python labelImg 图像标注工具安装及使用教程windows版(亲测有效)
  5. CentOs7.3 搭建 Solr单机服务
  6. BOOST库介绍(二)——BOOST多线程相关库
  7. Android VideoView播放视频详细步骤
  8. Git 技术篇 - github镜像推荐,无需翻墙实现飞速访问github官网
  9. vue js监听浏览器tab页切换
  10. 让项目经理受用终身的8个道理
  11. tkinter-canvas详解
  12. Linux多网卡多路由设置
  13. 重磅|中国PostgreSQL分会与中软国际全面战略合作协议签订
  14. html表单元素的colspan和rowspan合并单元格
  15. Beta分布(Beta Distribution)
  16. 软考信息系统项目管理师_招投标法_政府采购法---软考高级之信息系统项目管理师029
  17. PyTorch实战,基于GAN实现表情包生成
  18. mysql group by 季度_sql server如何按季度分组统计所有的数据
  19. 从提高练字效率思考如何学习技能
  20. LeetCode题解(0197):查询相较于昨天温度上升的日期(SQL)

热门文章

  1. centos静默安装oracle关于报错UnsatisfiedLinkError exception loading native library:njni10
  2. 线性代数第五版吉尔伯特课后答_线性代数同济第五版第六章课后习题答案!
  3. 最高调恋爱方式,简直“公开处刑”......
  4. 你发现了吗?数学还能这么美
  5. 对于“知识”,我们存在哪些误解?
  6. ajax和spa的区别,在XX团上消费过一次不正规的Spa,现在过来两个月公安局打电话叫我过去...
  7. 计算机信息处理教案,冀教版七年级信息技术第二课计算机--信息处理工具 教案...
  8. 楼层效果_1一28高楼最好最吉利的楼层是哪层?选楼层要注意什么?
  9. php header会重定向吗,php – 可以依靠header()重定向来结束程序流吗?
  10. axios请求拦截器错误_Axios使用拦截器全局处理请求重试