当前位置: 首页 > article >正文

leetcode-189:轮转数组

给定一个整数数组 nums,将数组中的元素向右轮转 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 <= 105
  • -231 <= nums[i] <= 231 - 1
  • 0 <= k <= 105

进阶:

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

步骤 1: 定义问题性质

给定一个整数数组 nums,需要将数组元素向右轮转 k 个位置。

输入条件:

  • nums 的长度在 [1, 10^5] 之间。
  • 数组元素的值在 [-2^31, 2^31 - 1] 之间。
  • 非负整数 k 的值在 [0, 10^5] 之间。

输出条件:

  • 返回一个数组,表示经过 k 次右轮转后的结果。

边界条件:

  • k 大于 nums 长度时,实际的轮转次数应为 k % nums.length
  • 如果 k 为 0,或者数组长度为 1,结果应为原数组。

步骤 2: 分解问题

  1. 处理 k 的值:计算有效的 k,即 k = k % nums.length
  2. 反转数组:将整个数组反转,这样最后 k 个元素会被放到开头。
  3. 反转子数组:分别反转前 k 个元素和后 n-k 个元素,以恢复顺序。

算法设计思路:

  • 反转算法是解决此类问题的有效方法,可以达到 O(n) 的时间复杂度和 O(1) 的空间复杂度。
  • 复杂度分析:
    • 时间复杂度:O(n),遍历数组三次。
    • 空间复杂度:O(1),使用常数额外空间。

数学证明

我们需要证明在给定整数数组 nums 和非负整数 k 的情况下,通过反转算法实现数组向右轮转 k 个位置的正确性。证明包括三个主要步骤。

定义和基础概念
  • 设数组长度为 n,初始数组为 nums
  • 向右轮转 k 个位置相当于将数组的最后 k 个元素移动到数组的开头,并将剩余的元素向后移动。
步骤 1: 计算有效的 k

在进行轮转之前,我们计算有效的 k: k′=kmod  nk' = k \mod nk′=kmodn 如果 k' 等于 0,则数组保持不变;否则,我们继续进行反转操作。

步骤 2: 反转整个数组

反转整个数组 nums: reverse(nums,0,n−1)\text{reverse}(nums, 0, n - 1)reverse(nums,0,n−1) 反转后的数组将变成: [last k′ elements,first (n−k′) elements][\text{last } k' \text{ elements}, \text{first } (n-k') \text{ elements}][last k′ elements,first (n−k′) elements]

例如,假设数组为 [1, 2, 3, 4, 5, 6, 7]k' = 3,反转后得到: [7,6,5,4,3,2,1][7, 6, 5, 4, 3, 2, 1][7,6,5,4,3,2,1]

步骤 3: 反转前 k' 个元素和后 n-k' 个元素
  1. 反转前 k' 个元素: reverse(nums,0,k′−1)\text{reverse}(nums, 0, k' - 1)reverse(nums,0,k′−1) 此时数组变为: [5,6,7,4,3,2,1][5, 6, 7, 4, 3, 2, 1][5,6,7,4,3,2,1]

  2. 反转后 n-k' 个元素: reverse(nums,k′,n−1)\text{reverse}(nums, k', n - 1)reverse(nums,k′,n−1) 最终得到: [5,6,7,1,2,3,4][5, 6, 7, 1, 2, 3, 4][5,6,7,1,2,3,4]

正确性证明

通过上述步骤,我们可以看到:

  • 初始反转将所有元素的位置完全改变,确保后续的反转能够有效地将目标元素排列到正确位置。
  • 对前 k' 个元素的反转确保了它们的顺序是正确的,因为这部分的元素在轮转后应该在数组的开始。
  • 对后 n-k' 个元素的反转同理,保证了这一部分的元素的顺序是正确的。

因此,经过这三个反转操作,最终数组呈现出经过 k 次右轮转的结果。

步骤 3: C++ 代码实现

步骤 4: 启发与优化

通过解决这个问题,可以认识到:

  • 反转算法是一种高效的数组处理技术,适用于各种旋转或重新排列问题。
  • 有效地利用模运算减少不必要的操作,可以提高程序性能。
  • 在处理大规模数据集时,算法的时间和空间复杂度的选择尤为重要,合理设计能显著提升效率。

步骤 5: 实际应用示例

应用场景:物流优化
在物流配送中,运输车辆常常需要根据不同的货物需求顺序重新安排送货顺序。通过应用此算法,可以高效地对送货路线进行调整。例如,当接到突发的送货请求时,系统可以迅速将当前配送路线向右轮转,以优先满足新的订单需求。这一过程可以通过实时数据更新来实现,确保配送效率。

具体实现方法:

  1. 将当前送货顺序表示为一个数组。
  2. 根据优先级调整需要发送的货物,计算新的送货顺序。
  3. 应用上述算法,实现高效轮转,并更新配送系统。

这样,物流公司可以快速响应市场变化,优化配送效率。


http://www.kler.cn/a/319996.html

相关文章:

  • 前端【2】html添加样式、CSS选择器
  • C# 获取PDF文档中的字体信息(字体名、大小、颜色、样式等
  • 修复5.0.0r 64位版本浏览器和一些库找不到的问题
  • 工作中redis常用的5种场景
  • 【蓝牙】win11 笔记本电脑连接 hc-06
  • 从玩具到工业控制--51单片机的跨界传奇【2】
  • 阿尔兹海默症患者出行随身助手设计_kaic
  • 【洛谷】P10417 [蓝桥杯 2023 国 A] 第 K 小的和 的题解
  • 免费制作证件照的小程序源码
  • 机器学习EDA探查工具Pandas profiling
  • nvm以及npm源配置
  • 注意力机制篇 | YOLOv8改进之在C2f模块引入EffectiveSE注意力模块 | 基于SE注意力
  • 聚观早报 | 豆包视频生成大模型发布;华为纯血鸿蒙将开启公测
  • 基于SpringBoot+Vue的考研百科网站系统
  • QT C++ 自学积累 『非技术文』
  • 数字IC设计\FPGA 职位经典笔试面试整理--基础篇2
  • TCP/IP 协议栈
  • 第五届计算机科学与管理科技国际学术会议(ICCSMT 2024)
  • 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-25
  • 【Hadoop】【vim编辑器】【~/.bashrc 文件】如何编辑
  • 计算机网络复习大纲
  • 二叉树的基本概念(下)
  • 技术成神之路:设计模式(十五)中介者模式
  • VulnHub-Bilu_b0x靶机笔记
  • 大数据新视界 --大数据大厂之HBase 在大数据存储中的应用与表结构设计
  • K8S精进之路-控制器StatefulSet有状态控制 -(2)