【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
- 追加の配列を使用して保存する
- 時間計算量: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つずつ移動します
- 時間計算量: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
- リング状に、0-> k-> 2k-> 3kを配置し、nk> = num.lengthまで、次にnk%num.length-> nk%num.length + kから;最後に0に戻します。
- 交換をいつ停止するかを判断するのが最も難しい、カウントを使用してカウントし、数が十分になったときに停止する
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%を上回っています