前端練習51 旋轉數組

已同步到個人博客,歡迎訪問


題目

題目來自LeetCode

給定一個數組,將數組中的元素向右移動k個位置,其中k是非負數。

示例 1:

輸入: [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:

輸入: [-1,-100,3,99] 和 k = 2
輸出: [3,99,-1,-100]
解釋: 
向右旋轉 1 步: [99,-1,-100,3]
向右旋轉 2 步: [3,99,-1,-100]

說明:

  • 儘可能想出更多的解決方案,至少有三種不同的方法可以解決這個問題。
  • 要求使用空間複雜度爲O(1)的原地算法。

實現

方法1

一個比較典型的旋轉問題

1234567k=3舉例:

先全部旋轉reverse(0, length-1),結果:

7654321

然後旋轉前k個數字,reverse(0, k-1),結果:

567  4321

最後旋轉剩餘數字:,reverse(k, length-1),結果:

567  1234

用代碼實現:

var rotate = function (nums, k) {
  let length = nums.length;
  // 處理k<n的情況
  k = k % length;
  // 旋轉
  function reverse(arr, start, end) {
    while (start < end) {
      [arr[start], arr[end]] = [arr[end], arr[start]];
      start++;
      end--;
    }
  }
  reverse(nums, 0, length - 1);
  reverse(nums, 0, k - 1);
  reverse(nums, k, length - 1);
  return nums
};

要注意k = k % length這行代碼,有兩個作用,一個是防止數組的長度小於k時出現錯誤,另一個是減少移動的次數

方法2

可以直接利用JS內置的插入的方法,它會自動將數組的序號更新(我怎麼把這個方法忘了)

var rotate = function (nums, k) {
  for (let i = 0; i < k; i++) {
    nums.unshift(nums.splice(nums.length-1, 1)[0])
  }
  return nums
};

方法3

又想了一個特笨的方法

還是以1234567k=3舉例

先從後向前進行第一輪移動,每相鄰兩項進行換位,結果是:

7123456

然後再進行第二輪移動,類似的,結果是:

6712345

k決定了移動的次數:

var rotate = function (nums, k) {
  while (k) {
    for (let i = nums.length - 1; i > 0; i--) {
      [nums[i], nums[i-1]] = [nums[i-1], nums[i]]
    }
    k--;
  }
  return nums
};

應該還有其他的方法,比如通過遞歸實現,回頭重新的時候再想吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章