【02】右旋函数(C语言)

目录

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

1.暴力求解(轮转k次)

2. 三段逆置求解

①逆置函数

②轮转函数

3.空间换时间求解



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

例如:

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

右旋三次后nums=[5,6,7,1,2,3,4]

1.暴力求解(轮转k次)

向右旋转 1 次:[7,1,2,3,4,5,6]

向右旋转 2 次:[6,7,1,2,3,4,5]

向右旋转 3 次:[5,6,7,1,2,3,4]

注:①如果k大于数组的总长度的话函数需要重复轮转多次,这时可以取模运算(也就是求余数)

       ②向右轮转时最后一个元素需要保存起来防止遗失,最后再将保存的最后一个元素的值赋给               第一个元素完成一次轮转;

       ③运用for循环轮转k次;

void rotate(int* nums,int numsSize, int k)
{k %= numsSize;//k大于numsSize取模,避免不必要的计算,小于numsSize取模则没有影响int i = 0;int tmp = 0;for (i = 0; i < k; i++){int a = numsSize;tmp = nums[a - 1];创建一个变量保存最后的数字while (a >= 2)//当(a-2)>=0时判定条件结束{nums[a - 1] = nums[a - 2];//将数组前一个值赋给后一个a--;}nums[0] = tmp;//将tmp中保存的数组最后一个元素的值赋给数组第一个元素}
}

 在vs2022上完整代码实现如下:

#include<stdio.h>
void rotate(int* nums,int numsSize, int k)
{k %= numsSize;//k大于numsSize取模,避免不必要的计算,小于numsSize取模则没有影响int i = 0;int tmp = 0;for (i = 0; i < k; i++){int a = numsSize;tmp = nums[a - 1];创建一个变量保存最后的数字while (a >= 2)//当(a-2)>=0时判定条件结束{nums[a - 1] = nums[a - 2];//将数组前一个值赋给后一个a--;}nums[0] = tmp;//将tmp中保存的数组最后一个元素的值赋给数组第一个元素}
}int main()
{int nums[7] = { 1,2,3,4,5,6,7 };int k = 3;rotate(nums,7, k);for (int i = 0; i < 7; i++)//打印轮转后的数组{printf("%d\n", nums[i]);}return 0;
}

运行结果如下:

以上就是暴力求解啦,关键是要一次一次的轮转,其时间复杂度为O(n^{2}),空间复杂度为O(1),对每次轮转的代码理解也极其重要哦~

2. 三段逆置求解

      @_@: "一个不一样的玩法,极其灵活的同时又极其难想,但它又像欧亨利式的结尾那般出人意料却又在情理之中"。

nums=[1,2,3,4,5,6,7]          k=3           n=7

①逆置函数

void reverse(int* nums, int left, int right)//逆置函数
{int tmp = 0;//创建一个中间变量while (left < right)//当左边等于右边时逆置结束{tmp = nums[right];nums[right] = nums[left];nums[left] = tmp;//左边和右边交换left++;right--;}}

②轮转函数

void rotate(int* nums, int numsSize, int k)//轮转函数
{k %= numsSize;reverse(nums, 0, numsSize - k - 1);//前n-k个逆置reverse(nums,0,3)reverse(nums, numsSize - k, numsSize - 1);后k个逆置//reversez(nums,4,6)reverse(nums, 0, numsSize - 1);//整体逆置reverse(nums,0,6)}

在vs2022上运行代码如下:

#include<stdio.h>
void reverse(int* nums, int left, int right)
{int tmp = 0;while (left < right){tmp = nums[right];nums[right] = nums[left];nums[left] = tmp;left++;right--;}
}
void rotate(int* nums, int numsSize, int k)
{k %= numsSize;reverse(nums, 0, numsSize - k - 1);//reverse(nums,0,3)reverse(nums, numsSize - k, numsSize - 1);//reversez(nums,4,6)reverse(nums, 0, numsSize - 1);//reverse(nums,0,6)}
int main()
{int nums[7] = { 1,2,3,4,5,6,7 };int k = 3;rotate(nums, 7, 3);for (int i = 0; i < 7; i++){printf("%d\n", nums[i]);}return 0;
}

结果如下:

 以上就是三段逆置啦,其时间复杂度为O(n),空间复杂度为O(1);最重要的就是它的思路三段逆置,其次就是逆置函数的实现。

3.空间换时间求解

开始:nums=[1,2,3,4,5,6,7]

结果:nums=[5,6,7,1,2,3,4]

所以如果有另外一个数组a先将nums中的{5,6,7}保存下来,再将{1,2,3,4}保存即可得到a=[5,6,7,1,2,3,4];最后将a拷贝到nums中即可,其时间复杂度较暴力求解大大减少为O(n),但空间复杂度变多为O(n);

注:①使用malloc开辟空间给a;

        ②使用memcpy函数来拷贝;(malloc、memcpy详情可见上一篇博客动态内存函数介绍【C语言】动态内存函数介绍-CSDN博客)

        ③malloc开辟的空间要记得free释放掉,并将指针置空

代码如下:

void rotate(int* nums, int numsSize, int k)
{k %= numsSize;int* a = (int*)malloc(sizeof(int) * numsSize);memcpy(a, nums + k +1 , sizeof(int) * (numsSize - k -1));//先将nums中的{5,6,7}保存下来memcpy(a + k,nums, sizeof(int) *(k+1));//再将{1,2,3,4}保存memcpy(nums, a, sizeof(int) * numsSize);//最后将a拷贝到nums中free(a);//释放掉开辟的空间a = NULL;//置空指针
}

在vs2022上完整运行代码如下:

void rotate(int* nums, int numsSize, int k)
{k %= numsSize;int* a = (int*)malloc(sizeof(int) * numsSize);memcpy(a, nums + k +1 , sizeof(int) * (numsSize - k -1));memcpy(a + k,nums, sizeof(int) *(k+1));memcpy(nums, a, sizeof(int) * numsSize);free(a);a = NULL;
}
int main()
{int nums[7] = { 1,2,3,4,5,6,7 };int k = 3;rotate(nums, 7, 3);for (int i = 0; i < 7; i++){printf("%d\n", nums[i]);}return 0;
}

运行结果如下:

以上就是空间换时间的方法啦,需要借助C语言中动态内存函数,对于动态内存函数的学习也必不可少哦,【C语言】动态内存函数介绍-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu 23.10通过APT安装Open vSwitch

正文共&#xff1a;888 字 8 图&#xff0c;预估阅读时间&#xff1a;1 分钟 先拜年&#xff01;祝各位龙年行大运&#xff0c;腾跃展宏图&#xff01; 之前在介绍OpenStack的时候介绍过&#xff08;什么是OpenStack&#xff1f;&#xff09;&#xff0c;OpenStack是一个开源的…

Acwing---839. 模拟堆

模拟堆 1.题目2.基本思想3.代码实现 1.题目 维护一个集合&#xff0c;初始时集合为空&#xff0c;支持如下几种操作&#xff1a; I x&#xff0c;插入一个数 x&#xff1b;PM&#xff0c;输出当前集合中的最小值&#xff1b;DM&#xff0c;删除当前集合中的最小值&#xff08…

蓝桥杯-X图形

问题描述 给定一个字母矩阵。一个 X 图形由中心点和由中心点向四个 45度斜线方向引出的直线段组成&#xff0c;四条线段的长度相同&#xff0c;而且四条线段上的字母和中心点的字母相同。 一个 X 图形可以使用三个整数 r,c,L 来描述&#xff0c;其中 r,c 表示中心点位于第 r 行…

Vue源码系列讲解——虚拟DOM篇【二】(Vue中的DOM-Diff)

目录 1. 前言 2. patch 3. 创建节点 4. 删除节点 5. 更新节点 6. 总结 1. 前言 在上一篇文章介绍VNode的时候我们说了&#xff0c;VNode最大的用途就是在数据变化前后生成真实DOM对应的虚拟DOM节点&#xff0c;然后就可以对比新旧两份VNode&#xff0c;找出差异所在&…

基于大语言模型的AI Agents

代理&#xff08;Agent&#xff09;指能自主感知环境并采取行动实现目标的智能体。基于大语言模型&#xff08;LLM&#xff09;的 AI Agent 利用 LLM 进行记忆检索、决策推理和行动顺序选择等&#xff0c;把Agent的智能程度提升到了新的高度。LLM驱动的Agent具体是怎么做的呢&a…

java_error_in_pycharm.hprof文件是什么?能删除吗?

java_error_in_pycharm.hprof文件是什么&#xff1f;能删除吗&#xff1f; &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;hprof格式文件介绍&#x1f333;&#x1f333;java_error_in_pycharm.hprof文件什么情况下能删除&#x1f333;&…

Docker-Learn(二)保存、导入、使用Docker镜像

1.保存镜像 根据上一节内容&#xff0c;将创建好镜像进行保存&#xff0c;需要退出当前的已经在运行的docer命令行中断里面&#xff0c;可以通过在终端里面输入指令exit或者按下键盘上的 ctrlD建退出&#xff1a; 回到自己的终端里面&#xff0c;输入指令&#xff1a; docker…

跟着cherno手搓游戏引擎【23】项目维护、2D引擎之前的一些准备

项目维护&#xff1a; 修改文件结构&#xff1a; 头文件自己改改就好了 创建2DRendererLayer&#xff1a; Sandbox2D.h: #pragma once #include "YOTO.h" class Sandbox2D :public YOTO::Layer {public:Sandbox2D();virtual ~Sandbox2D() default;virtual void O…

微软.NET6开发的C#特性——类、结构体和联合体

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;看到不少初学者在学习编程语言的过程中如此的痛苦&#xff0c;我决定做点什么&#xff0c;下面我就重点讲讲微软.NET6开发人员需要知道的C#特性&#xff0c;然后比较其他各种语言进行认识。 C#经历了多年发展…

第77讲用户管理功能实现

用户管理功能实现 前端&#xff1a; views/user/index.vue <template><el-card><el-row :gutter"20" class"header"><el-col :span"7"><el-input placeholder"请输入用户昵称..." clearable v-model"…

Linux第43步_移植ST公司uboot的第4步_uboot测试

uboot移植结束后&#xff0c;需要进行测试。 1、烧录程序 1)、将STM32MP157开发板的网络接口与路由器的网络接口通过网线连接起来。 2)、将开发板的串口和电脑通过USB线连接起来。 3)、将开发板的USB OTG接口和电脑通过USB线连接起来。 4)、将开发板上拨码开关拨到“000”…

「Linux」用户操作

root用户 su&#xff1a;切换账户 语法&#xff1a;su [–] [用户名] -&#xff1a;可选&#xff0c;表示是否在切换用户后加载环境变量&#xff0c;建议带上用户名&#xff1a;表示要切换的用户&#xff0c;省略时表示切换到root切换用户后&#xff0c;通过exit命令退回上一个…

LocalAI 部署(主要针对 mac m2 启动)

LocalAI 部署 介绍 LocalAI 是免费的开源 OpenAI 替代方案。 LocalAI 充当 REST API 的直接替代品&#xff0c;与本地推理的 OpenAI API 规范兼容。 它无需 GPU&#xff0c;还有多种用途集成&#xff0c;允许您使用消费级硬件在本地或本地运行 LLM、生成图像、音频等等&#…

spring boot(2.4.x 开始)和spring cloud项目中配置文件application和bootstrap加载顺序

在前面的文章基础上 https://blog.csdn.net/zlpzlpzyd/article/details/136060312 spring boot 2.4.x 版本之前通过 ConfigFileApplicationListener 加载配置 https://github.com/spring-projects/spring-boot/blob/v2.3.12.RELEASE/spring-boot-project/spring-boot/src/mai…

Apache 神禹(shenyu)源码阅读(一)——Admin向Gateway的数据同步(Admin端)

源码版本&#xff1a;2.6.1 单机源码启动项目 启动教程&#xff1a;社区新人开发者启动及开发防踩坑指南 源码阅读 前言 开了个新坑&#xff0c;也是第一次阅读大型项目源码&#xff0c;写文章记录。 在写文章前&#xff0c;已经跑了 Divide 插件体验了一下&#xff08;体…

Codeforces Round 113 (Div. 2)E. Tetrahedron(dp、递推)

文章目录 题面链接题意题解代码总结 题面 链接 E. Tetrahedron 题意 从一个顶点出发走过路径长度为n回到出发点的方案总数 题解 考虑dp f [ i ] [ 0 ∣ 1 ∣ 2 ∣ 3 ] f[i][0|1|2|3] f[i][0∣1∣2∣3]:走了i步&#xff0c;现在在j点的方案总数 转移&#xff1a; f [ i ]…

【Linux进程间通信】用管道实现简单的进程池、命名管道

【Linux进程间通信】用管道实现简单的进程池、命名管道 目录 【Linux进程间通信】用管道实现简单的进程池、命名管道为什么要实现进程池&#xff1f;代码实现命名管道创建一个命名管道 理解命名管道匿名管道与命名管道的区别命名管道的打开规则 作者&#xff1a;爱写代码的刚子…

【C语言进阶】深度剖析数据在内存中的存储--上

1. C语言中的数据类型的简单介绍 注&#xff1a;C99标准里面&#xff0c;定义了bool类型变量。这时&#xff0c;只要引入头文件stdbool.h &#xff0c;就能在C语言里面正常使用bool类型。 1.1 在C语言中各类型所占内存空间的大小如下 char类型的数据类型大小为1字节即8比特位。…

蓝桥杯每日一题------背包问题(三)

前言 之前求的是在特点情况下选择一些物品让其价值最大&#xff0c;这里求的是方案数以及具体的方案。 背包问题求方案数 既然要求方案数&#xff0c;那么就需要一个新的数组来记录方案数。动态规划步骤如下&#xff0c; 定义dp数组 第一步&#xff1a;缩小规模。考虑n个物品…

云原生容器化-4 Docker仓库

1.Docker仓库 1.1 Docker Hub docker仓库用于存放docker镜像&#xff0c;可以分为公用和私有两种。Docker Hub是全球公用的仓库&#xff0c;因服务器在国外&#xff0c;国内基本不可以&#xff1b;一般需要配置阿里、腾讯等加速器。公司内部而言&#xff0c;可以搭建私有的Do…