前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【02】右旋函数(C语言)

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

作者头像
大耳朵土土垚
发布于 2024-03-13 10:40:55
发布于 2024-03-13 10:40:55
10700
代码可运行
举报
文章被收录于专栏:c/c++c/c++
运行总次数:0
代码可运行

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

例如:

nums7 = {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大于数组的总长度的话函数需要重复轮转多次,这时可以取模运算(也就是求余数)

代码语言:txt
复制
   ②向右轮转时最后一个元素需要保存起来防止遗失,最后再将保存的最后一个元素的值赋给               第一个元素完成一次轮转;
代码语言:txt
复制
   ③运用for循环轮转k次;
代码语言:javascript
代码运行次数:0
运行
复制
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上完整代码实现如下:

代码语言:javascript
代码运行次数:0
运行
复制
#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}
n^{2}

),空间复杂度为O(1),对每次轮转的代码理解也极其重要哦~

2. 三段逆置求解

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

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

①逆置函数

代码语言:javascript
代码运行次数:0
运行
复制
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--;
	}

}

②轮转函数

代码语言:javascript
代码运行次数:0
运行
复制
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上运行代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
#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;

代码语言:txt
复制
    ②使用memcpy函数来拷贝;(malloc、memcpy详情可见上一篇博客动态内存函数介绍[【C语言】动态内存函数介绍-CSDN博客](https://blog.csdn.net/Renswc/article/details/135727657))
代码语言:txt
复制
    ③malloc开辟的空间要记得free释放掉,并将指针置空哦

代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
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上完整运行代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
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博客

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-03-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
​LeetCode刷题实战189:旋转数组
算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !
程序员小猿
2021/03/04
2460
数据结构初步(二)- oj练习-时间与空间复杂度
进阶: 尽可能想出更多的解决方案,至少有三种 不同的方法可以解决这个问题。 你可以使用空间复杂度为
怠惰的未禾
2023/04/27
2670
数据结构初步(二)- oj练习-时间与空间复杂度
C语言---数据结构(1)--时间复杂和空间复杂度计算
时间效率被称为时间复杂度,而空间效率被称作空间复杂度。 时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间,在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度,现在主要关注的是空间效率
Undoom
2024/09/23
1190
C语言---数据结构(1)--时间复杂和空间复杂度计算
Leetcode----旋转数组 ------C语言篇
🐶给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
小李很执着
2024/06/15
790
【Leetcode -面试题17.04.消失的数字 -189.轮转数组】
我们的思路是将所有的数异或在一起,然后再将结果异或0-N,得到的最后结果就是消失的数字; 原理:a ^ a = 0 ; 0 ^ a = a.
YoungMLet
2024/03/01
1210
【C语言刷题系列】轮转数组
倔强的石头_
2024/12/06
850
【C语言刷题系列】轮转数组
了解时间复杂度和空间复杂度
在学习数据结构前,我们需要了解时间复杂度和空间复杂度的概念,这能够帮助我们了解数据结构。
用户11039545
2024/05/04
980
了解时间复杂度和空间复杂度
[c语言日记]轮转数组算法(力扣189)
在编程的世界里,数组操作是基础且常见的任务之一。今天,我们来探讨一个有趣且实用的数组操作问题——轮转数组。这个问题不仅考验我们对数组的理解,还能帮助我们深入理解算法的优化过程。
siy2333
2025/04/15
700
力扣(LeetCode)初级算法--旋转数组
旋转数组 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
程序员小涛
2020/12/03
2550
力扣旋转字符串
题目链接:(来源于力扣)(右旋) 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1:
初阶牛
2023/03/08
3280
力扣旋转字符串
轮转数组(超详细!)
小编在上一篇文章的时候拿过轮转数组作为例子来讲述复杂度,但是小编并没有给出这个题目的正确解答,既然读者朋友已经了解复杂度了(不了解也没关系,可以看小编上一篇·文章),下面,跟随小编的脚步开始进入此习题的讲解!
用户11295429
2024/10/16
1170
轮转数组(超详细!)
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
算法效率分析分为两种:第一种是时间效率,第二种是空间效率。时间效率被称为时间复杂度,而空间效率被称作空间复杂度。 时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间,在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度。
爱喝兽奶的熊孩子
2024/04/21
1.4K0
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
顺序表、链表相关OJ题(2)
注:这是常规思路,但是由于空间复杂度太高,数组个数特别多的时候,在力扣运行的时候超出了时间限制!
小陈在拼命
2024/02/17
1330
顺序表、链表相关OJ题(2)
漫画:三次反转旋转数组
第189题:给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
程序员小浩
2020/03/31
6980
LeetCode数组高频题目整理
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
嵌入式与Linux那些事
2021/05/20
1.7K0
LeetCode数组高频题目整理
【初阶数据结构】算法复杂度
对于我们所要解决的问题来说,解决的方法各有不同,每个人各有各的道理,并且受制于所用的设备的性能环境不同,我们很难精确比较一些方法不太明显的差别,因此,如何脱离环境直接衡量一个算法本身的好坏呢?比如对于以下斐波那契数列:
ZLRRLZ
2024/12/13
1290
【初阶数据结构】算法复杂度
【初阶数据结构与算法】复杂度分析练习之轮转数组(多种方法)
题目链接:https://leetcode.cn/problems/rotate-array/description/    为什么我们把这道题作为复杂度的练习题呢?是因为我们以后做题都会涉及到复杂度的计算,我们要保证我们写的程序不会超出题目的时间和空间的要求    这道题就可以给我们一些启发,比如这道题有的方法复杂度过高,超出了题目要求的时间或者是空间限制,我们就需要计算我们方法的时间和空间复杂度找出问题,然后及时的换另一种方法,不死磕一个方法
TANGLONG
2024/11/19
940
【初阶数据结构与算法】复杂度分析练习之轮转数组(多种方法)
leetcode-189. 旋转数组
尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。 你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?
全栈程序员站长
2022/09/22
1530
LeetCode 189. 旋转数组(环形替换)
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/rotate-array 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
Michael阿明
2020/07/13
6360
LeetCode 189. 旋转数组(环形替换)
189. 旋转数组
在这个方法中,我们首先将所有元素反转。然后反转前 k 个元素,再反转后面 n-k个元素,就能得到想要的结果。
Michel_Rolle
2021/02/01
2.9K0
相关推荐
​LeetCode刷题实战189:旋转数组
更多 >
目录
  • 题目:给定一个整数数组nums,将数组中的元素向右轮转k个位置,其中k是非负数。
  • 1.暴力求解(轮转k次)
  • 2. 三段逆置求解
    • ①逆置函数
    • ②轮转函数
  • 3.空间换时间求解
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档