[LeetCode] 189. Rotate Array(Medium)(JAVA)1日1つの質問

【LeetCode】189。アレイの回転(中)(JAVA)

タイトルアドレス:https//leetcode.com/problems/rotate-array/

タイトル説明:

配列が与えられたら、配列をkステップ右に回転します。ここでkは負ではありません。

ファローアップ:

  • できるだけ多くの解決策を考え出すようにしてください。この問題を解決するには、少なくとも3つの異なる方法があります。
  • O(1)の余分なスペースでインプレースでそれを行うことができますか?

例1:

Input: nums = [1,2,3,4,5,6,7], k = 3
Output: [5,6,7,1,2,3,4]
Explanation:
rotate 1 steps to the right: [7,1,2,3,4,5,6]
rotate 2 steps to the right: [6,7,1,2,3,4,5]
rotate 3 steps to the right: [5,6,7,1,2,3,4]

例2:

Input: nums = [-1,-100,3,99], k = 2
Output: [3,99,-1,-100]
Explanation: 
rotate 1 steps to the right: [99,-1,-100,3]
rotate 2 steps to the right: [3,99,-1,-100]

制約:

  • 1 <= nums.length <= 2 * 10 ^ 4
  • -2 ^ 31 <= nums [i] <= 2 ^ 31-1
  • 0 <= k <= 10 ^ 5

一般的なアイデア

配列が与えられたら、配列の要素をkの位置から右に移動します。ここで、kは非負の数です。

説明:

  • できるだけ多くの解決策を考えてください。この問題を解決するには、少なくとも3つの異なる方法があります。
  • スペースの複雑さがO(1)のインプレースアルゴリズムを使用する必要があります。

問題解決方法

方法1

  1. 追加の配列を使用して保存する
  2. 時間計算量:O(n)、空間計算量:O(n)
class Solution {
    public void rotate(int[] nums, int k) {
        if (nums.length == 0) return;
        k = k % nums.length;
        int[] res = new int[nums.length];
        for (int i = 0; i < k; i++) {
            res[i] = nums[nums.length - k + i];
        }
        for (int i = k; i < nums.length; i++) {
            res[i] = nums[i - k];
        }
        for (int i = 0; i < nums.length; i++) {
            nums[i] = res[i];
        }
    }
}

実行時間:9ミリ秒、Javaユーザーの54.92%を打ち負かす
メモリ消費量:41.1 MB、Javaユーザーの16.91%を打ち負かす

方法2

  1. 一度に1つずつ移動します
  2. 時間計算量:O(kn)、空間計算量:O(1)
class Solution {
    public void rotate(int[] nums, int k) {
        if (nums.length <= 1) return;
        k = k % nums.length;
        if (k == 0) return;
        int temp = nums[nums.length - 1];
        for (int i = nums.length - 1; i > 0; i--) {
            nums[i] = nums[i - 1];
        }
        nums[0] = temp;
        rotate(nums, k - 1);
    }
}

実行時間:265ミリ秒、Javaユーザーの20.95%を上回っています
メモリ消費量:39.9 MB、Javaユーザーの5.13%を上回っています

方法3

  1. リング状に、0-> k-> 2k-> 3kを配置し、nk> = num.lengthまで、次にnk%num.length-> nk%num.length + kから;最後に0に戻します。
  2. 交換をいつ停止するかを判断するのが最も難しい、カウントを使用してカウントし、数が十分になったときに停止する
class Solution {
    public void rotate(int[] nums, int k) {
        if (nums.length <= 1) return;
        k = k % nums.length;
        if (k == 0) return;
        int count = 0;
        for (int i = 0; i < k && count < nums.length; i++) {
            int pre = nums[i];
            int next = (i + k) % nums.length;
            while (next != i) {
                int temp = nums[next];
                nums[next] = pre;
                pre = temp;
                next = (next + k) % nums.length;
                count++;
            }
            nums[i] = pre;
            count++;
        }
    }
}

実行時間:0ミリ秒、Javaユーザーの100.00%を上回っています
メモリ消費量:39 MB、Javaユーザーの75.85%を上回っています

私の公式アカウントに注意を払うことを歓迎します、LeetCodeは毎日1つの質問を更新します

おすすめ

転載: blog.csdn.net/qq_16927853/article/details/112344586