LC-189. 轮转数组

168 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目描述

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

题解

  • 数组翻转

    • 先将原数组进行翻转后

    • 再处理K值,让其值在 [0,nums.length)

    • 对其 [0~K),[k~nums.length)分别再进行翻转

    • 最后即可得到结果值

    image.png

        const reverse = (nums, start, end) => {
          while (start < end) {
            const temp = nums[start]
            nums[start] = nums[end]
            nums[end] = temp
            start += 1
            end -= 1
          }
        }
    
        const rotate = (nums, k) => {
          k %= nums.length
          reverse(nums, 0, nums.length - 1)
          reverse(nums, 0, k - 1)
          reverse(nums, k, nums.length - 1)
        }
    

    这种方法需要一个较好的思路,能够对数组有一个很好的理解,算是思维的一种扩展。

  • 通过js的暴力解法(不考虑时间限制)

    还是先对K值进行处理,让其值在 [0,nums.length)。之后通过 js 数组中的 popunshift 这两个方法来进行处理。

        const rotate = (nums, k) => {
          k %= nums.length
          for (i = 0; i < k; i++) {
            nums.unshift(nums.pop())
          }
        }
    
  • 额外数组空间

    创建一个新的数组,数组长度与原数组长度相同,通过求余映射,将对应的值放入,最终得到结果。

        const rotate = (nums, k) => {
          const n = nums.length
          const newArr = new Array(n)
          for (let i = 0; i < n; ++i) {
            newArr[(i + k) % n] = nums[i]
          }
          for (let i = 0; i < n; ++i) {
            nums[i] = newArr[i]
          }
        }
    

总结

题目 2,有3种甚至更多种解法,优先考虑第一种和第三种,第二种在没有时间的限制下,可以使用。