LeetCode 189.轮转数组 (双指针)

2023-05-16

题目传送门:轮转数组

题目详情:

给你一个数组,将数组中的元素向右轮转 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 <= 10^5
  • -2^31 <= nums[i] <= 2^31 - 1
  • 0 <= k <= 10^5

题目分析和代码:

起初并没有看到提示部分,自认为给的数组并不会很大,然后也没有深入思考,立刻就将代码写了出来。

初始超时代码(c++):

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int length=nums.size()-1;//数组下标最大值
        while(k)//数组每向右移动一次执行一次循环直至移动k次
        {
            int t=nums[length];
            for(int i=length;i>0;i--)//将数组第一个元素至倒数第二个元素中的每个元素都向右移动一位
            {
                nums[i]=nums[i-1];
            }
            nums[0]=t;
            k--;
        }
    }
};

时间复杂度为O(k*n),空间复杂度为O(1),虽然空间复杂度低但时间复杂度直接拉满了,题目数组范围太大因此在第35个测试用例超时了,当时我还很奇怪,点开查看最后的输入时才发现原来数组范围居然会这么大,开始认真思考解题方法了。

拿示例一来分析:输入: nums = [1,2,3,4,5,6,7], k = 3   输出: [5,6,7,1,2,3,4]

先将数组下标标出来:()内为数组下标

输入: nums = [1(0),2(1),3(2),4(3),5(4),6(5),7(6)]

输出:              [5(0),6(1),7(2),1(3),2(4),3(5),4(6)]

从上面我们可以看出数组下标为0的1移动到了数组下标为3的位置,数组下标为1的2则移动到了数组下标为4的位置,数组下标为6的7移动到了数组下标为2的位置,从其中我们可以发现元素下标的移动规律为:移动到(数组下标n+k)%数组长度的数组位置,(0+3)%7=3,(6+3)%7=2;找到规律后再将答案放到一个新开辟空间的数组中最后再转到原数组中,时间复杂度为O(n),空间复杂度为O(n)

第一次ac代码(c++):

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int length=nums.size();
        vector<int>ans(length,0);
        for(int i=0;i<=length-1;i++)
        {
            int dis=(i+k)%length;
            ans[dis]=nums[i];
        }
        for(int i=0;i<=length-1;i++)
        {
            nums[i]=ans[i];
        }
    }
};

这样发现题目还是比较简单的,但是题目进阶要求时间复杂度为O(n),空间复杂度为O(1),空间复杂度为O(1)确实有点困难,看了官方题解三后发现居然还有这么神奇的方法,下面就简单讲解一下数组翻转的方法。

还是拿示例一来分析:输入: nums = [1,2,3,4,5,6,7], k = 3   输出: [5,6,7,1,2,3,4]

我们发现尾部k%数组长度的元素(5,6,7)移动到了数组头部,而其余元素则向后移动了k%数组长度的位置。

我们可以先将数组所有元素进行翻转,这样尾部的元素就会到达数组头部位置,然后再将头部前k%数组长度的元素翻转保证数组元素的顺序不变,然后再将其他元素进行翻转。

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

先将数组所有元素进行翻转:                                           nums = [7,6,5,4,3,2,1]

然后再将头部3%7(7为数组长度)=前3个元素进行翻转:  nums = [5,6,7,4,3,2,1]

再将其他元素进行翻转:                                                  nums = [5,6,7,1,2,3,4]

输出: [5,6,7,1,2,3,4]

数组翻转的代码(c++):

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        k %= nums.size();
        reverse(nums.begin(),nums.end());//翻转整个数组元素
        reverse(nums.begin(),nums.begin()+k);//翻转前k个元素
        reverse(nums.begin()+k,nums.end());//翻转其余元素
    }
};

reverse为c++函数,可以实现翻转数组,字符串,向量,使用时需要包含头文件<algorithm> 。

使用方法:翻转数组:reverse(a,a+n)n为数组元素个数;翻转vector中的元素或字符串时则为reverse(vec.begin() ,vec.end() ) 和 reverse(str.begin() ,str.end() )。

题目要求将数组进行向右旋转,如果是向左旋转的话只用将第一行翻转代码改到最后一行就行了,即为先翻转前n个元素,再翻转其余元素,最后翻转数组所有元素。

 时间复杂度为O(n),空间复杂度为O(1)

 环状替换代码(c++):

我们从初始位置 0 开始,最初令pre=nums[0]。可以得出位置 0 的元素会放到 (0+k)%n的位置,令 x= (0+k)%n,然后交换 pre 和 nums[x],完成位置 x 的更新。然后,我们继续研究位置 x,并交换 pre 和 nums[(x+k)%n],从而完成下一个位置的更新。如果回到初始起点0时还有元素未进行翻转,则将起点位置+1,然后重复上述内容直至一共翻转了n个元素(翻转完成)。

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int length=nums.size(),count=length;
        int i=0,pos=0,pre=nums[pos];//pre会不断更新成被覆盖的元素
        if (k % length == 0)
            return;
        while (count--)//一共要对n个元素进行翻转,n为元素个数 
        {
            pos = (pos + k) % length;
            swap(nums[pos], pre);
            if (pos == i)//如果回到起点且还有未遍历过的元素时
            {
                pos = ++i;
                pre = nums[pos];
            }
        }
    }
};

时间复杂度为O(n),空间复杂度为O(1)

计算机204 zjr

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LeetCode 189.轮转数组 (双指针) 的相关文章

  • Ubuntu 更新apt出错

    输入sudo apt get update后出现 Err 1 http us archive ubuntu com ubuntu xenial InRelease Temporary failure resolving 39 us arch
  • 使用OpenWrt开发嵌入式Linux(二):先让系统跑起来(使用initramfs)

    安装相关工具 推荐使用ubuntu 16及以上版本 sudo apt install gcc binutils bzip2 flex python perl make diffutils unzip gawk subversion zlib
  • 使用kubeadm从0到1搭建kubernete集群

    目录 概述 安装前提示 安装docker 安装kubeadm 安装kubernete集群master节点 安装 kubeadm kubectl kubelet组件 安装kubernete master节点 安装CNI网络插件 部署集群wor
  • shell基础之变量(2):变量有哪些种类、怎么定义/赋值/取值、不同种类变量的作用域

    通过本文能对shell变量有一个系统性的了解 xff0c 具体的包括 xff1a 变量的种类 xff1a 局部 全局 环境变量变量的定义和操作 xff1a 赋值 取值 取消变量变量的作用域 文章目录 一 变量的种类1 全局变量2 局部变量
  • java 泛型全解 - 绝对最详细

    背景 对于java的泛型我一直属于一知半解的 xff0c 平常真心用的不多 直到阅读 Effect Java 看到很多平常不了解的用法 xff0c 才下定决心 xff0c 需要系统的学习 xff0c 并且记录下来 1 泛型的概述 xff1a
  • Zookeeper数据同步流程

    在服务器启动阶段 xff0c 会进行磁盘数据的恢复 xff0c 完成数据恢复后就会进行Leader选举 一旦选举产生Leader服务器后 xff0c 就立即开始进行集群间的数据同步 xff0c 在整个过程中 xff0c Zookeeper都
  • JS中Ajax的方法和应用

    XMLHttpRequest对象 Ajax技术的核心是XMLHttpRequest对象 xff08 简称XHR xff09 这是有微软率先引入的一个特性 xff0c 其他浏览器提供商后来都提供了相同的实现 但因为IE的兼容性问题 xff0c
  • node.js安装及环境配置

    一 下载nodejs的安装包 xff1a 下载地址 xff1a https nodejs org zh cn download 根据自己电脑系统及位数选择 xff0c 一般都选择windows64位 msi格式安装包 网站上提供的安装包版本
  • 6个常用的React组件库

    Ant Design 项目链接 xff1a Ant Design 包大小 xff08 来自 BundlePhobia xff09 xff1a 缩小后 1 2mB xff0c 缩小 43 gzip 压缩后 349 2kB xff0c 通过摇树
  • 大数据培训课程数据清洗案例实操-简单解析版

    数据清洗 xff08 ETL xff09 在运行核心业务MapReduce程序之前 xff0c 往往要先对数据进行清洗 xff0c 清理掉不符合用户要求的数据 清理的过程往往只需要运行Mapper程序 xff0c 不需要运行Reduce程序
  • 宋红康2023版Java视频发布

    1500万 43 播放量见证经典 xff0c 尚硅谷宋红康老师的Java入门视频堪称神作 xff0c 如今经典再次超级进化 xff0c 新版Java视频教程震撼来袭 xff01 开发环境全新升级 xff1a JDK17 43 IDEA202
  • Java消息队列:消息在什么时候会变成Dead Letter?

    在较为重要的业务队列中 xff0c 确保未被正确消费的消息不被丢弃 xff0c 通过配置死信队列 xff0c 可以让未正确处理的消息暂存到另一个队列中 xff0c 待后续排查清楚问题后 xff0c 编写相应的处理代码来处理死信消息 一 什么
  • Vue2和Vue3数据双向绑定原理的区别及优缺点(下篇)

    上篇我们讲到了Vue2的数据双向绑定原理 xff0c 如果你没有阅读上篇 xff0c 建议先阅读一下上篇中的内容 Vue2和Vue3数据双向绑定原理的区别及优缺点 xff08 上篇 xff09 在上篇中我们抛出了一个问题 xff1a 是不是
  • FlinkTable时间属性

    像窗口 xff08 在 Table API 和 SQL xff09 这种基于时间的操作 xff0c 需要有时间信息 因此 xff0c Table API 中的表就需要提供逻辑时间属性来表示时间 xff0c 以及支持时间相关的操作 一 处理时
  • kafka学习(1)

    目录 kafka是什么 xff1f 为什么要用kafka kafka的特点 kafka结构 Kafka Producer的Ack机制 kafka是什么 xff1f 收集nginx日志 xff0c 将nginx日志的关键字段进行分析 xff0
  • spss 因子分析

    是通过研究变量间的相关系数矩阵 xff0c 把这些变量间错综复杂的关系归结成少数几个综合因子 xff0c 并据此对变量进行分类的一种统计方法 xff0c 归结出的因子个数少于原始变量的个数 xff0c 但是他们又包含原始变量的信息 xff0
  • Hive 报错 Invalid column reference 列名

    两张表 当我执行 select m movieid m moviename substr m moviename 5 4 as years avg r rate as avgScore FROM t movie as m join t ra
  • 20数学建模C-中小微企业的信贷决策

    前言 源码文末获取 小编在 9 月份参加了今年的数学建模 xff0c 成绩怎么样不知道 xff0c 能有个成功参与奖就不错了哈哈 最近整理了一下 xff0c 写下这篇文章分享小编的思路 能力知识水平有限 xff0c 欢迎各位大佬前来指教 o
  • playwright 爬虫使用

    官方文档 xff1a Getting started Playwright Python 参考链接 xff1a 强大易用 xff01 新一代爬虫利器 Playwright 的介绍 目录 安装 基本使用 代码生成 AJAX 动态加载数据获取
  • kmeans聚类选择最优K值python实现

    来源 xff1a https www omegaxyz com 2018 09 03 k means find k 下面利用python中sklearn模块进行数据聚类的K值选择 数据集自制数据集 xff0c 格式如下 xff1a 维度为3

随机推荐

  • mysql构造页损坏

    构造页损坏 及修复方式可参考 gg gMysql页面crash问题复现 amp 恢复方法 阿里云开发者社区 也可通过 dd 命令进行构造 dd xff0c 命令参考 xff1a Linux dd 命令 菜鸟教程
  • mysql审计日志过滤sql功能

    审计日志功能是一个插件 xff0c 需要先安装插件才可以使用 过滤 sql 语句 xff0c 可以通过插件内核参数 audit log include commands 与 audit log exclude commands 参数设置 x
  • setDaemon python守护进程,队列通信子线程

    使用setDaemon 和守护线程这方面知识有关 xff0c 比如在启动线程前设置thread setDaemon True xff0c 就是设置该线程为守护线程 xff0c 表示该线程是不重要的 进程退出时不需要等待这个线程执行完成 这样
  • 中文与 \u5927\u732a\u8e44\u5b50 这一类编码互转

    了解更多关注微信公众号 木下学Python 吧 a 61 39 大猪蹄子 39 a 61 a encode 39 unicode escape 39 print a 运行结果 xff1a b 39 u5927 u732a u8e44 u5b
  • python字典删除键值对

    https blog csdn net uuihoo article details 79496440
  • 计算机网络(4)传输层

    目录 小知识点 xff1a 三次握手 xff1a 状态 xff1a tcpdump xff1a 一 xff1a 命令介绍 xff1a 二 xff1a 命令选项 xff1a tcpdump的表达式 xff1a 使用python扫描LAN工具
  • MSE 治理中心重磅升级-流量治理、数据库治理、同 AZ 优先

    作者 xff1a 流士 本次 MSE 治理中心在限流降级 数据库治理及同 AZ 优先方面进行了重磅升级 xff0c 对微服务治理的弹性 依赖中间件的稳定性及流量调度的性能进行全面增强 xff0c 致力于打造云原生时代的微服务治理平台 前情回
  • TF多层 LSTM 以及 State 之间的融合

    第一是实现多层的LSTM的网络 第二是实现两个LSTM的state的concat操作 分析 state 的结构 对于第一个问题 之前一直没有注意过 看下面两个例子 在这里插入代码片 import tensorflow as tf num u
  • 实例讲解PMP相关方参与度评估矩阵

    在规划相关方参与计划过程中 xff0c 会用到相关方参与度评估矩阵 如下图所示 在上图中 xff0c C 代表每个相关方的当前参与水平 xff0c D 是项目团队评估出来的 为确保项目成功所必不可少的参与水平 xff08 期望的 xff09
  • 在Mac OS中安装 wget

    先从Apple Store下载Xcode xff0c 然后安装Xcode 接着安装Homebrew包管理 xff0c 类似于Ubuntu下的apt get xff0c 终端下输入 xff1a ruby span class hljs ope
  • 前端与产品经理配合

    产品经理PM职业介绍 如何构建原型图 axure软件
  • C++ 重载运算符

    C 43 43 重载运算符号 本文针对结构体重载运算符号进行讲解 其实这是一个困扰我蛮久的问题 xff0c 就是结构体如何使用sort函数进行排序 xff0c 去网上找了很多 xff0c 满多都是关于类的 xff0c 虽然类跟结构体只有访问
  • &运算符的用法

    按位与运算符 34 amp 34 是双目运算符是参与运算的两数各对应的二进位相与 按位与 34 amp 34 功能是参与运算的两数各对应的二进位相与 只有对应的两个二进位均为1时 xff0c 结果位才为1 xff0c 否则为0 参与运算的数
  • 火柴棒游戏(暴力枚举)C++

    暴力枚举 P1149 NOIP2008 提高组 火柴棒等式 题目描述 xff1a 给你n根火柴棍 xff0c 你可以拼出多少个形如 A 43 B 61 CA 43 B 61 C 的等式 xff1f 等式中的AA BB CC是用火柴棍拼出的整
  • 2021蓝桥杯B组 G题砝码称重

    题目大意 xff1a 解法一 xff1a 首先想到的是可以用广度优先搜索的方式来进行暴力求解 xff0c 通过使用递归来将每一种方法遍历 xff0c 并且标记 xff0c 不过由于此方法的时间复杂度是O n3 故使用暴力搜索只能完成50 的
  • 2021蓝桥杯B组 第I题杨辉三角形

    第I题 杨辉三角形 题目大意 xff1a 解法一 xff1a xff08 得20 xff09 思路 xff1a 当指考虑小范围的值时 xff0c 我们可以直接根据杨辉三角形的规律 xff1a 第i行第j列的值 61 第i 1行第j列的值 4
  • Docker--安装Docker和简单使用

    1 docker的安装 1 首先先有一台配置高的虚拟机 xff08 至少两核四G xff09 2 按官方文档 Install Docker Engine on CentOS Docker Documentation 删除docker软件包
  • 力扣 1697. 检查边长度限制的路径是否存在

    给你一个 n 个点组成的无向图边集 edgeList xff0c 其中 edgeList i 61 ui vi disi 表示点 ui 和点 vi 之间有一条长度为 disi 的边 请注意 xff0c 两个点之间可能有 超过一条边 给你一个
  • c++stl 学习心得

    一 c 43 43 和c的区别 xff1a 1 函数默认值 在C 43 43 中我们在定义或声明一个函数的时候 xff0c 有时会在形参中给它赋一个初始值作为不传参数时候的缺省值 xff0c 例如 xff1a int is xff08 in
  • LeetCode 189.轮转数组 (双指针)

    题目传送门 xff1a 轮转数组 题目详情 xff1a 给你一个数组 xff0c 将数组中的元素向右轮转 k 个位置 xff0c 其中 k 是非负数 示例 1 输入 nums 61 1 2 3 4 5 6 7 k 61 3 输出 5 6 7