LeetCode.189(轮转数组)

news2024/9/24 3:27:14

对于轮转数组这个题,文章一共提供三种思路,对于每种思路均提供其对应代码的时间、空间复杂度。

目录

1. 创建变量来保存最后一个数,并将其余数组向前挪动一位 :

1.1 原理解析:

1.2 代码实现:

 2.创建一个数组,用于存放需要旋转的元素,并放到相应位置:

2.1 原理解析:

2.2 代码实现:

3. 先左部分右旋,再右部分右旋,最后整体逆序(三段逆序法):

3.1 原理解析:

 3.2 代码实现:


题目要求如图所示:

 

1. 创建变量来保存最后一个数,并将其余数组向前挪动一位 :

(注:第一种思路虽然可以解决问题,但是代码的时间复杂度为O(N^2),空间复杂度为O(1),时间复杂度不符合LeetCode的提交标准,所以,第一种思路仅供参考与扩展。)

1.1 原理解析:

 假设一个数组为:

nums[7] = {1,2,3,4,5,6,7};

为了方便表示,用下图来代表数组及数组中的元素:

第一步:先将数组种最后一位元素,即:7,用一个临时变量保存。

 

第二步:将其他剩余元素全部向右移动一位。

 

第三步: 把临时变量保存的7,放到数组的首元素的位置。

 

 至此,完成一次交换。

1.2 代码实现:

用代码表示上述过程,即:

#include<stdio.h>
#include<assert.h>
void rotata(int* nums,int numsize)
{
	assert(nums);
	int tmp = nums[numsize - 1];//用临时变量保存数组最后一个元素
	int i = 0;
	for (i = 6 ; i > 0; i--)
	{
		nums[i] = nums[i - 1];//将其余元素向右移动一位
	}
	nums[0] = tmp;//将临时变量保存的元素放在数组首个元素的位置
}
int main()
{
	int nums[7] = { 1,2,3,4,5,6,7 };
	int sz = sizeof(nums) / sizeof(nums[0]);
	rotata(nums, sz );
	return 0;
}

打印结果如下:

 

上面的代码,只能实现右移一位。对于移动多个元素,可以将上面移动一个元素的过程用循环来进行。例如,用变量k来代表旋转的次数,代码为:

#include<stdio.h>
#include<assert.h>
void rotata(int* nums,int numsize,int k)
{
    k = k % numsize + 1;//防止k过大,使k的范围在0-7
	assert(nums);
	int j = 0;
	for (j = 0; j < k; j++)
	{
		int tmp = nums[numsize - 1];//用临时变量保存数组最后一个元素
		int i = 0;
		for (i = 6; i > 0; i--)    //0 1 2 3 4 5 6 
			                       //  1 2 3 4 5 6
		{
			nums[i] = nums[i - 1];//将其余元素向右移动一位
		}
		nums[0] = tmp;//将临时变量保存的元素放在数组首个元素的位置
	}
	
	
}
int main()
{
	int nums[7] = { 1,2,3,4,5,6,7 };
	int sz = sizeof(nums) / sizeof(nums[0]);
	int k = 0;
	scanf("%d", &k);
	rotata(nums, sz,k );
	int i = 0;

	return 0;
}

因为数组每旋转7次,数组中的元素就回到不旋转的位置,所以,即使在输入旋转次数为77次时,得到的效果也和旋转一次一样

旋转一次效果:

旋转两次效果:

 

旋转77次:

 

但是,当k的值过大时,因为每右旋7次就是一个循环,所以,为了减少编译器的工作量,用k%numsize+1,让k的取值范围保持在0\rightarrow 7这个区间(闭区间)

 2.创建一个数组,用于存放需要旋转的元素,并放到相应位置:

方法二的时间复杂度为O(N),空间复杂度为O(N)

2.1 原理解析:

依旧使用上面的图来解释思路:

右旋一次:

 右旋两次:

对于上面的两种情况,不难发现,其实所谓的右旋,可理解为将需要进行右旋的元素看成一个整体,让后放到其余元素的前面,例如旋转两次时:

第一步:将元素6,7看作一个整体,其余元素看成一个整体。

 

第二步:作为整体的6,7放到剩余元素的前面进行整合:

 

2.2 代码实现:

有了解决问题的思路后,下面给出具体实现的代码:

void rotate(int* nums, int numsSize, int k){
   int n = numsSize;
   int* tmp = (int*)malloc(sizeof(int)*(n));
  
   k = k%n;

   memcpy(tmp,nums+n-k,sizeof(int)*(k));
   memcpy(tmp+k,nums,sizeof(int)*(n-k));
   memcpy(nums,tmp,sizeof(int)*(n));

   free(tmp);

}

 整体代码的逻辑为: n是数组中元素的个数,k是执行右旋的次数。

1.先用malloc开辟一块空间 

2.用k%n来限制k的取值范围。

3.先利用memcpy函数将nums数组种起始地址n+k,数量为k的元素拷贝到tmp这个临时空间种。

4.再利用memcpy函数将nums剩余的元素拷贝到tmp中。

此时,tmp已经存储了旋转后的数组。

5.将tmp中的元素赋值到nums中。

执行结果如下:

 从结果中可以看到,方法二是用空间来换取速度的方法。

3. 先左部分右旋,再右部分右旋,最后整体逆序(三段逆序法):

最优解法,时间复杂度为O(N),空间复杂度因为只创建了一个额外的临时变量,为O(1)

3.1 原理解析:

对于三段逆序法,同样使用图片来解释:

假设:数组名为nums,数组中的元素个数为n,按照LeetCode中7个元素。需要旋转的位数为k。下面的代码就拿k = 3来解释。

第一步:先将左部分元素整体逆序,即:把下标从0到nums-k-1(即数组中第一个到第四个元素逆序)的元素逆序:

 

第二步:将右半部分元素整体逆序,即:把下标为nums - kn-1(即数组中第五个到第七个元素逆序):

第三步:整体逆序:即:对下标从0到nums-1的元素逆序:

通过LeetCode网站给出的样例发现,整体逆序后结果与样例相同:

 

 3.2 代码实现:

  在上面的解释中,既然每一步都需要逆序,所以,为了方便并且减少代码量,可以提前封装一个交换函数或者直接使用交换函数,这里给出提前封装交换函数的代码:

其中:变量a对应数组nums,变量left对应交换的起始位置,变量right对于交换的结束位置

void reserve( int*a,int left,int right)
{
    while(left < right)
    {
        int tmp = a[left];
        a[left] = a[right];
        a[right] = tmp;
        left++;
        right--;
    }
}

再交换后,根据上面对原理的解释,对逆序函数进行三次调用并传递相应的参数即可:

void rotate(int* nums, int numsSize, int k){

   int n = numsSize;
   k = k%n;
   reserve(nums,0,n-k-1);
   reserve(nums,n-k,n-1);
   reserve(nums,0,n-1);

}

整体函数如下:

void reserve( int*a,int left,int right)
{
    while(left < right)
    {
        int tmp = a[left];
        a[left] = a[right];
        a[right] = tmp;
        left++;
        right--;
    }
}


void rotate(int* nums, int numsSize, int k){

   int n = numsSize;
   k = k%n;
   reserve(nums,0,n-k-1);
   reserve(nums,n-k,n-1);
   reserve(nums,0,n-1);

}

运行结果如下:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/797246.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【学习笔记】行为识别SOTA方法比较

这里写目录标题 前言方法1 基于CNN的方法Slow-fast&#xff1a; 2 基于Vision-Transformer的方法Video TimeSformer :Video Swin Transformer : 3、基于自监督的方法VideoMAE&#xff1a; 4、基于多模态的方法Intern video: 前言 常用行为识别数据集包括&#xff1a;HMDB-51、…

TL-ER3220G设置vlan

TL-ER3220G是企业宽带路由器。 自带5个RJ45接口。 其中接口1到接口4都可以接入宽带线路。最多可以并接4路。 本例由接口1接入宽带&#xff0c;默认接口2到接口4组成1个vlan&#xff0c;名称vlan。其中接口5特殊&#xff0c;带宽最大100M。 计划将接口2和接口4组成第一个vlan&…

STM32使用HAL库BH1750光照度传感器

开发环境 单片机&#xff1a;STM32F103C8T6 光照度传感器&#xff1a;BH1750 IDE&#xff1a;KEILSTM32CUBEMX 单片机配置 1、STM32CUBEMX BH1750代码 1、头文件 /* ************************************************* BH1750光照数据计算&#xff08;LUX&#xff09; …

H5和小程序测试点分析

最近接触了较多关于H5页面的测试&#xff0c;H5页面的测试除了业务逻辑功能测试外&#xff0c;其他部分的测试方法基本是可以通用的&#xff0c;在此对H5页面和小程序的一些通用测试方法进行总结分享给大家。 H5优势&#xff1a; 1.H5可以跨平台&#xff0c;开发成本相对较低…

中共湖南麒麟信安科技股份有限公司委员会召开庆祝建党102 周年暨“七一”表彰大会

为隆重庆祝中国共产党成立 102 周年&#xff0c;6月30日下午&#xff0c;中共湖南麒麟信安科技股份有限公司委员会召开庆祝建党102 周年暨“七一”表彰大会。麒麟信安党委书记王忠锋出席会议&#xff0c;党委副书记李广辉主持会议&#xff0c;全体党委委员、各支部委员、受表彰…

Gitlab 合并分支与请求合并

合并分支 方式一&#xff1a;图形界面 使用 GitGUI&#xff0c;右键菜单“GitExt Browse” - 菜单“命令” - 合并分支 方式二&#xff1a;命令行 在项目根目录下打开控制台&#xff0c;注意是本地 dev 与远程 master 的合并 // 1.查看本地分支&#xff0c;确认当前分支是否…

Elasticsearch-增删改查数据工作原理

集群 集群的基本概念&#xff1a; 集群&#xff1a;ES 集群由一个或多个 Elasticsearch 节点组成&#xff0c;每个节点配置相同的 cluster.name 即可加入集群&#xff0c;默认值为 “elasticsearch”。节点&#xff1a;一个 Elasticsearch 服务启动实例就是一个节点&#xff…

伦敦银定盘价机制的改变

一直以来&#xff0c;伦敦都是全球最大的现货白银定价中心&#xff0c;LBMA也是全球金银市场中最具有影响力的机构组织&#xff0c;其定盘价一直是世界各白银市场基准价的主要参考标准&#xff0c;被广泛应用于生产厂商、消费者和金融机构之间的交易结算&#xff0c;也是众多白…

刷题DAY 11

题目一 给定一个整型数组arr&#xff0c;和一个整数num某个arr中的子数组sub&#xff0c;如果想达标&#xff0c;必须满足&#xff1a;sub中最大值-sub中最小值<num&#xff0c;返回arr中达标子数组的数量 滑动窗口法,滑动窗口有两个行为1.右括 2.左缩 错误想法1: 当你已经…

工频耐压测试仪的使用方法

一、凯迪正大工频耐压试验装置使用方法 1、核对试验变压器&#xff0c;测量绕阻额定输出电压&#xff0c;使之与操作箱&#xff08;台&#xff09;相吻合。 2、按接线示意图接好试验变压器与操作箱&#xff08;台&#xff09;及感应调压器之间的联线。 3、接通电源&#xff0c;…

索引能优化查询,那么谈谈索引的优点和缺点?索引原理

面试必备&#xff1a;索引能优化查询&#xff0c;那么谈谈索引的优点和缺点?索引原理 简述&#xff1a; 优点: 第一&#xff0c;通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。 第二&#xff0c;可以大大加快数据的检索速度&#xff0c;这也是创建…

工程设计施工3D模型素材下载,全套1000+免费获取

在建筑设计和施工过程中&#xff0c;3D模型数据是至关重要的。设计师和工程师需要依赖高质量的3D模型数据进行方案优化、细节设计、施工规划和质量控制。因此&#xff0c;如何下载高质量的3D模型数据成为了一个重要的问题。 今天给大家免费提供一个“设计、施工3D模型数据下载…

推荐几个不错的免费配色工具网站

1. Paletton专业的配色套件,提供色轮理论及调色功能。可查看配色预览效果。 网站:http://paletton.com 2. Colormind一个基于机器学习的智能配色工具。可以一键生成配色方案。 网站:http://colormind.io 3. Adobe ColorAdobe官方的配色工具,可以从图片中取色,也可以随机生成配色…

ModStartCMS v6.9.0 后台多标签改进,主题色自动切换修复

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用&#xff0c;支持后台一键快速安装&#xff0c;让开发者能快的实现业务功能开发。 系统完全开源&#xff0c;基于 Apache 2.0 开源协议&#xff0c;免费且不限制商业使用。 功能特性 丰富的模块市…

docker安装MySQL集群(一主一从)

目录 docker安装MySQL集群&#xff08;一主一从&#xff09;前菜测试MySQL 集群安装master容器slave容器master容器配置主从赋值测试 docker安装MySQL集群&#xff08;一主一从&#xff09; 前菜测试 1、拉取mysql5.7的镜像到本地 [rootaliyun ~]# docker pull mysql:5.72、…

优思学院|丰田公司的精益生产为什么让人敬佩?

因为丰田精益生产方式的成功不是偶然&#xff0c;它历经了50多年&#xff0c;从员工的教育训练着手&#xff0c;使他们能运用非常严格的问题解决程序&#xff0c;采用科学方法&#xff0c;针对各项活动、流程及制度不断地加以评估、检测与改进而自然形成的。事实上&#xff0c;…

【阿Q送书第四期】好书推荐《重构的时机和方法》

文章目录 背景概念介绍案例目录购书 送书规则 背景 最近公司正在组织 Code Review &#xff0c;看看之前为了赶项目写的代码&#xff0c;真的是一言难尽。所以想趁同事审查我的代码之前做点“小动作”&#xff0c;没错&#xff0c;我想说的就是“代码重构”。 对于工作时间较…

css设置背景图片和边框背景

介绍一个网站&#xff0c;在这个网站里可以找到各种好看的背景图片和边框图片。 数据大屏 &#xff08;代码是reactts&#xff0c;使用时请自行转换&#xff09; 一&#xff1a;设置页面背景图片 css部分 .productionBoard {width: 100%;height: 100%;padding: 0 2rem;box-si…

高效梳理商业模式,3个免费的精益画布模板网站!

精益画布是一种能够帮助创业者快速开发商业模式的工具&#xff0c;它广泛应用于初创公司、企业创新、新产品发布等领域&#xff0c;并且精益画布可以帮助创业者系统地归纳商业模式&#xff0c;并从中找到新的商业机会。本文将向大家介绍3款免费的精益画布模板网站&#xff0c;这…

SFP3012-ASEMI快恢复二极管参数、规格、尺寸

编辑&#xff1a;ll SFP3012-ASEMI快恢复二极管参数、规格、尺寸 型号&#xff1a;SFP3012 品牌&#xff1a;ASEMI 芯片个数&#xff1a;2 芯片尺寸&#xff1a;102MIL*2 封装&#xff1a;TO-247 恢复时间&#xff1a;65ns 工作温度&#xff1a;-40C~175C 浪涌电流&am…