C语言三种方法解决轮转数组问题

 更新时间:2022年04月22日 11:45:22   作者:平凡的人1  
这篇文章主要给大家讲解轮转数组的问题,一个问题不局限于一种解法,希望你看了本文的解决方法以后可以举一反三自己编写,这样你的技术水平会有质的提高

题目

1.题目描述

给你一个数组,将数组中的元素向右轮转 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.要求

进阶:

  • 尽可能想出更多的解决方案,至少有 三种 不同的方法可以解决这个问题。
  • 你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?

3.原题链接

 189. 轮转数组 - 力扣(LeetCode) (leetcode-cn.com)

二、相关知识点

本题实际上涉及到了复杂度的问题,包括时间复杂度和空间复杂度。

三、解决思路

旋转法

最优思路,这需要我们有较好的理解力了,可以把数组分为三个部分

假设我们需要选择k个数字:

1.后k个数字逆置

2.前n-k个数字逆置

3.整体逆置

此方法为最优法。符合题目要求

以示例 1为例子说明:

1 2 3 4 5 6 7//旋转3个数字
1 2 3 4 7 6 5//后k个数字逆置
4 3 2 1 7 6 5//前n-k个数字逆置
5 6 7 1 2 3 4//整体逆置

源代码如下:

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-k-1);
    reverse(nums,numsSize-k,numsSize-1);
    reverse(nums,0,numsSize-1);
}

注意点:k的大小可能大于数组的大小,所以我们要取模!

这个算法的时间复杂度为O(N),空间复杂度为O(1)

附上结果运行图:

直接法

看到这道题,我们的第一种想法就是直接去旋转,当k=1是。我们就直接把最后一位的数字移动第一位,然后第二位开始往后移动,我们可以创建一个临时的变量来记录当前的最后一位,当k很大时,我们自然就是用循环去做,这是每个人都能想得到的一种方法

代码如下

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

遗憾的是,这种算法的空间复杂(k*N),没能跑得过去,超时了,给出运行结果图

空间换取时间

以空间换取时间,这是比较常见的,就是额外开辟一个数组,存放选择的几个数字,然后将之前的数据存储到该数组的后半部分。最后将新数组拷贝到原来的数组中

代码如下

void rotate(int* nums, int numsSize, int k){
   k %= numsSize;
   int *newnum = (int*)malloc(sizeof(int)*numsSize);
   int j = 0;
   for(int i =numsSize-k;i<numsSize;i++){
       newnum[j++] =nums[i];
   }
   for(int i = 0;i<numsSize-k;i++){
       newnum[i+k] = nums[i];
   }
   memcpy(nums,newnum,sizeof(int)*numsSize);
}

运行结果如图

虽然也是通过了,但是效率不如思路一。

到此这篇关于C语言三种方法解决轮转数组问题 的文章就介绍到这了,更多相关C语言轮转数组内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++ COM编程之QueryInterface函数(二)

    C++ COM编程之QueryInterface函数(二)

    这篇文章主要介绍了C++ COM编程之QueryInterface函数(二),本文是第二篇,第一篇请参阅相关文档,需要的朋友可以参考下
    2014-10-10
  • C 语言基础教程(我的C之旅开始了)[二]

    C 语言基础教程(我的C之旅开始了)[二]

    C 语言基础教程(我的C之旅开始了)[二]...
    2007-02-02
  • C++ win系统如何用MinGW编译Boost库

    C++ win系统如何用MinGW编译Boost库

    这篇文章主要介绍了C++ win系统如何用MinGW编译Boost库问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • c语言打印输出双引号的方法示例

    c语言打印输出双引号的方法示例

    这篇文章主要介绍了c语言打印输出双引号的方法,大家参考使用吧
    2013-11-11
  • C语言实现将字符和数字串到一起

    C语言实现将字符和数字串到一起

    今天小编就为大家分享一篇C语言实现将字符和数字串到一起,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • 简单讲解c++ vector

    简单讲解c++ vector

    这篇文章主要介绍了c++ vector的相关资料,帮助大家更好的理解和学习c++,感兴趣的朋友可以了解下
    2020-09-09
  • C和C++的区别详解

    C和C++的区别详解

    这篇文章主要介绍了C和C++之间的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-10-10
  • vs2019创建dll以及使用的图文教程

    vs2019创建dll以及使用的图文教程

    本文主要介绍了vs2019创建dll以及使用的图文教程,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • C++的输入和输出流详解

    C++的输入和输出流详解

    这篇文章主要为大家详细介绍了C++的输入和输出流,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • C++设计模式之Static Factory模式详解

    C++设计模式之Static Factory模式详解

    这篇文章主要为大家详细介绍了C++设计模式之Static Factory模式的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07

最新评论