当前位置: 首页 > news >正文

轮转数组——深度解剖逆转算法的奥秘

◆ 博主名称: 小此方-CSDN博客

大家好,欢迎来到小此方的博客。

🔥个人专栏:《C语言》_小此方的博客-CSDN博客

算法_小此方的博客-CSDN博客

🔥 努力成就未来,代码改变世界,相信我有一天也能成为改变世界的那个人


目录

一,暴力解

二,创建新数组

三,翻转算法

一,翻转算法的步骤

二,左旋与右旋?

数学上的重要发现:

三,怎么想到的


先看题:

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

示例 1:

输入: nums = [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:
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释: 
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]

一,暴力解

➤看到这道题目,想必大家第一时间会想到最暴力的方法:

存储最后一个元素,然后将所有元素向后移动一格,最后将这个元素放在数组的第一位。

  while(k){int a = nums[numsSize-1];int i=numsSize-2;while(i>=0){nums[i+1] = nums[i];i--;}nums[0]=a;k--;}

但,事实上,这个算法的时间复杂度是O(N),有没有其他更厉害的方法?

二,创建新数组

int arr[numsSize] ;int i=0;int j=k;while(i<k&&j>0){arr[i]=nums[numsSize-j];i++;j--;}int n=k;int m=0;while(m < numsSize-k){arr[n]=nums[m];n++;m++;}int q=0;while(q<numsSize){nums[q] = arr[q];q++;}

➤ 通过观察,我们不难发现,轮转后的数组有两部分组成,以此为例:

4,5,6,7,1,2,3

➤ 我们可以将它拆分成5,6,7和1,2,3,4两个部分。因此,我们想到了创建一个新的数组的方法,如图:

三,翻转算法

  //算法二//先让前n-k个数字反转//0------k-1k = k % numsSize; // 关键:处理 k 大于数组长度的情况if (k == 0) return; // 如果不需要旋转,直接返回int front01=0;int end01 = numsSize-k-1;while(front01<=end01){int mid01 = nums[front01];nums[front01] = nums[end01];nums[end01] = mid01;front01++;end01--;}//再让后k个数字反转int front02 = numsSize-k;int end02 = numsSize-1;while(front02<=end02){int mid02=nums[front02];nums[front02]=nums[end02];nums[end02]=mid02;front02++;end02--;}//整体再反转int front = 0;int end = numsSize-1;while(front<=end){int mid=nums[front];nums[front]=nums[end];nums[end]= mid;front++;end--;}

✦ 暴击消耗的时间复杂度高

✦ 创建新数组消耗的空间复杂度高

那么,在“创建新数组的思想”基础之上,有没有能原地修改的办法?

翻转算法能解决这个问题。

一,翻转算法的步骤

✦ 先对前面一部分(前)数据翻转,

✦ 再对后面一部分(后)数据翻转,

✦ 最后在整体翻转。

“我们如何定义一部分?”先不急——,我们先来讲一讲:翻转算法的方向问题:

二,左旋与右旋?

右旋转定义:元素向右移动,右边的元素从尾部回到头部

左旋转定义:元素向左移动,左边的元素从头部回到尾部

如图,如果数组向右旋转,那么数组后面的数字会依次被放置在数组前面,数组前面的元素依次向后移动一位。————即轮转k次

✦ 先对前面一部分(前)数据翻转,

✦ 再对后面一部分(后)数据翻转,

这里就指一部分(前)=k;一部分(后)=n-k;

反之,左旋:一部分(前)=n-k;一部分(后)=k;

简单来说:

  • 如果k表示右旋步数,就反转前 n-k 个

  • 如果k表示左旋步数,就反转前 k 个

数学上的重要发现:

右旋k位 = 左旋(n-k)位
左旋k位 = 右旋(n-k)位

三,怎么想到的

这种思路来源于一个已知的数学事实:

对序列 (X Y),想变成 (Y X),可以:

  1. 反转 X → X'

  2. 反转 Y → Y'

  3. 反转整体 (X' Y') → Y X

在字符串旋转、链表旋转等问题中都有类似技巧。
它本质上是利用了反转操作的双重应用可以重置部分顺序的性质。

http://www.dtcms.com/a/587383.html

相关文章:

  • 外贸网站建设 义乌wordpress 3.9.1
  • 网站开发包含网站维护吗网站建设可行性分析报告模板
  • 广东企业网站seo点击软件意大利设计网站
  • 深圳做网页的网站平面设计课程简介
  • 嘉兴网站建设网站做网站需要前置审批
  • 培训网站推荐网站地图生成器
  • 菏泽网站建设方案wordpress 标签详解
  • 大理州城乡建设局官方网站百度公司有哪些部门
  • 网站备案会掉吗下载免费网络
  • 的网站制作利津网站建设哪家好
  • 百度推广怎么做的网站网站运营实例
  • 商城网站功能最好网站建设公司制作平台
  • 西安网站开发公司价格微商城网站建设策划
  • 韶关建设网站dw代码写完之后怎么运行网页
  • 官方网站怎么推广一个简单网页的代码
  • mini-program [food health preservation]
  • 一个网站需要多少钱如何选择网站开发公司
  • 网站ip指向列表家居装修设计平台
  • 网站里做任务wordpress免费插件
  • 网站 建设设计义乌网络推广公司
  • 网站建设的总体设计概图网站编辑需要的技能
  • 兰陵建设局网站微信网站制作哪个好
  • 网站建设详情页wordpress程序员博客主题
  • 自己怎么做网站建设化妆品网站建设经济可行性分析
  • 网页广告设计收费长沙优化网站哪家公司好
  • 行业门户网站模板国家企业信用信息
  • 用户体验较好的网站seo网站的优化方案
  • 安徽城乡建设厅网站怎么做淘课网站
  • 图书馆网站设计方案cms做门户网站
  • 自己搭建服务器 发布网站 域名如何申请任县建设局网站