IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【LeetCode·数组.189】旋转数组,题目分析+三种思路+知识点总结 -> 正文阅读

[数据结构与算法]【LeetCode·数组.189】旋转数组,题目分析+三种思路+知识点总结

旋转数组


来源: 力扣(LeetCode)
链接: 189.旋转数组


一、题目

给定一个数组,将数组中的元素向右移动 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:

输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释: 
向右旋转 1: [99,-1,-100,3]
向右旋转 2: [3,99,-1,-100]

提示:

1 <= nums.length <= 2 * 104
-231 <= nums[i] <= 231 - 1
0 <= k <= 105


二、解题思路分析

1. 暴力循环求解

按照它的思路,旋转k次,把旋转k次分成k份,每份都是旋转1次

先保存最后一个数字,往前的每一个数字都向后挪一位
在这里插入图片描述

但力扣好像会溢出

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

    for(i = 0; i < k; i++)//交换k次
    {
        int ret = *(nums + numsSize -1);

        for(j = 0; j < numsSize - 1; j++)//交换一次
        {
            nums[numsSize - 1 - j] = nums[numsSize - 2 - j];
        }
        nums[0] = ret;

    }

}

如果用内存拷贝代码会简单一点

void rotate(int* nums, int numsSize, int k){
    int i = 0;
    for(i = 0; i < k; i++)
    {
        int ret = nums[numsSize - 1];
        memmove(nums + 1, nums, (numsSize - 1) * sizeof(int));
        nums[0] = ret;

    }
}

时间复杂度:O(kn)

空间复杂度:O(1)


2. 额外数组,利用空间换时间

可以使用额外的数组来将每个元素放至正确的位置

创建数组的时候,虽然在oj中可以

int newArr[numsSize];

????但在编译器中是不允许的

在这里插入图片描述

????会出现错误

这样我们先用malloc开辟内存空间

void rotate(int* nums, int numsSize, int k){
    int* tmp = (int*)malloc(sizeof(int) * numsSize);
    if(tmp == NULL)
    {
        exit(-1);
    }    
}

将每个数的正确位置放在新的数组里,最后复制到原数组中,最后别忘记释放内存空间

在这里插入图片描述

void rotate(int* nums, int numsSize, int k){
    int* tmp = (int*)malloc(sizeof(int) * numsSize);
    if(tmp == NULL)
    {
        exit(-1);
    }

    int i = 0;
    for(i = 0; i < numsSize; i++)
    {
        tmp[(i + k) % numsSize] = nums[i];

    }
    for (int i = 0; i < numsSize; ++i) 
    {
        nums[i] = tmp[i];
    }
    free(tmp);
    tmp =NULL;
    
}

时间复杂度:O(2n)

空间复杂度:O(n)


3. 数组翻转

类似于字符串翻转,在字符串中我们遇到,字符串倒序/字符串翻转/字符串左旋

abcdef -> cdefab

我们先将 ab 逆序 -> ba

再将 cdef 逆序 -> fedc

最后将 ba fedc 逆序

得到 cdefab

数组可以用同样的方式

void reverse(int* nums, int numsSize)
{
    int i = 0;
    int ret = 0;
    for(i = 0; i < numsSize/2; i++)
    {
        ret = nums[i];
        nums[i] = nums[numsSize - 1 - i];
        nums[numsSize - 1 - i] = ret;
    }

}

void rotate(int* nums, int numsSize, int k){
    k = k % numsSize;
    if(k > 0)
    {
        reverse(nums, numsSize - k);
        reverse(nums + numsSize - k, k);
        reverse(nums, numsSize);
    }

    
}

三、总结

知识点总结:

  • 🎵数组中头插
  • 🎵学会用空间换取时间
  • 🎵翻转数组中元素

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-20 12:44:30  更:2021-10-20 12:44:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:52:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码