ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

轮转数组(C语言)

2021-12-18 17:33:43  阅读:176  来源: 互联网

标签:numsSize tmp 轮转 nums int C语言 数组


文章目录

【题目描述】
给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

题目来源(力扣):轮转数组

示例1:
输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]

示例2:
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]

注:0 <= k <= 10^5

在讲这道题之前,我们首先要知道这么一个点:
如果一个数组有 n 个元素,那么当它向右轮转了 n 步之后,整个数组跟原来一样。
也就是 k = n 的效果跟 k = 0 的效果是一样的,
即对 k 做这样的处理: k %= numsSize 即可。(对 k >= n 都成立)

思路正确但不实际的解法

基本思路:
先复制最后一个元素,然后将前面的元素都向右轮转一步,最后将原来的最后的元素放到首元素位置。把这个操作循环 k 次,就能得到结果。

void rotate(int* nums, int numsSize, int k){
    k %= numsSize;
    
    for(int i = 0; i < k; i++)
    {
        int tmp = nums[numsSize - 1];
        for(int j = numsSize - 1; j > 0; j--)
        {
            nums[j] = nums[j - 1];
        }
        nums[0] = tmp;
    }
}

但是这种方法的时间复杂度是 O(n^2),效率太低,特别是在数据量很大的情况下。
可行但不实际,所以大胆舍弃它。

解法一

基本思路:
开辟额外的数组,把每个元素放到新开辟的数组的轮转 k 步后的位置,最后再复制回原数组。
总的来说就是以空间换时间,通过牺牲一定的空间来优化时间效率。

void rotate(int* nums, int numsSize, int k){
    int* tmp = (int*)malloc(sizeof(int)*numsSize);
    
    for (int i = 0; i < numsSize; i++) 
    {
        tmp[(i + k) % numsSize] = nums[i];  //把每个元素放到新开辟的数组的轮转 k 步后的位置
    }
    
    for(int i = 0; i < numsSize; i++)
    {
        nums[i] = tmp[i];
    }
    
    free(tmp);
    tmp = NULL;
}

时间复杂度是 O(n),空间复杂度也是O(n),还是可行的,但存在额外的空间开销。

解法二

这种方法很巧,没接触过类似题型的大概想不到。

基本思路:
先把整体逆序,然后根据 k 把数组划分为两部分,分别逆序这两部分。

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


void rotate(int* nums, int numsSize, int k){
    k %= numsSize;

    reverse(nums, 0, numsSize - 1);
    reverse(nums, 0, k - 1);
    reverse(nums, k, numsSize - 1);
}

时间复杂度是 O(n),空间复杂度是O(1),不需要额外的空间开销即可解决问题,算得上是最优解了。

更多文章
采用快慢指针法来解决有关数组的问题(C语言)
异或的妙用(C语言)
大数相加(C语言)
合并两个有序数组(C语言)
阶乘后的零(C语言)
调整数组顺序使奇数位于偶数前面(C语言)

标签:numsSize,tmp,轮转,nums,int,C语言,数组
来源: https://blog.csdn.net/m0_59938453/article/details/122013159

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有