Skip to content

Commit ea108f5

Browse files
committed
feat: add solutions to lc problem: No.0189
No.0189.Rotate Array
1 parent 6e4ee0e commit ea108f5

File tree

10 files changed

+307
-238
lines changed

10 files changed

+307
-238
lines changed

solution/0100-0199/0189.Rotate Array/README.md

+113-78
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,23 @@
5353

5454
<!-- 这里可写通用的实现逻辑 -->
5555

56-
`k=3``nums=[1,2,3,4,5,6,7]`
56+
**方法一:三次翻转**
5757

58-
先将 `nums` 整体翻转:`[1,2,3,4,5,6,7]` -> `[7,6,5,4,3,2,1]`
58+
我们不妨记数组长度为 $n$,然后将 $k$ 对 $n$ 取模,得到实际需要旋转的步数 $k$。
5959

60-
再翻转 `0~k-1` 范围内的元素:`[7,6,5,4,3,2,1]` -> `[5,6,7,4,3,2,1]`
60+
接下来,我们进行三次翻转,即可得到最终结果:
6161

62-
最后翻转 `k~n-1` 范围内的元素,即可得到最终结果:`[5,6,7,4,3,2,1]` -> `[5,6,7,1,2,3,4]`
62+
1. 将整个数组翻转
63+
2. 将前 $k$ 个元素翻转
64+
3. 将后 $n - k$ 个元素翻转
65+
66+
举个例子,对于数组 $[1, 2, 3, 4, 5, 6, 7]$, $k = 3$, $n = 7$, $k \bmod n = 3$。
67+
68+
1. 第一次翻转,将整个数组翻转,得到 $[7, 6, 5, 4, 3, 2, 1]$。
69+
2. 第二次翻转,将前 $k$ 个元素翻转,得到 $[5, 6, 7, 4, 3, 2, 1]$。
70+
3. 第三次翻转,将后 $n - k$ 个元素翻转,得到 $[5, 6, 7, 1, 2, 3, 4]$,即为最终结果。
71+
72+
时间复杂度 $O(n)$,其中 $n$ 为数组长度。空间复杂度 $O(1)$。
6373

6474
<!-- tabs:start -->
6575

@@ -70,16 +80,16 @@
7080
```python
7181
class Solution:
7282
def rotate(self, nums: List[int], k: int) -> None:
73-
"""
74-
Do not return anything, modify nums in-place instead.
75-
"""
83+
def reverse(i: int, j: int):
84+
while i < j:
85+
nums[i], nums[j] = nums[j], nums[i]
86+
i, j = i + 1, j - 1
87+
7688
n = len(nums)
7789
k %= n
78-
if n < 2 or k == 0:
79-
return
80-
nums[:] = nums[::-1]
81-
nums[:k] = nums[:k][::-1]
82-
nums[k:] = nums[k:][::-1]
90+
reverse(0, n - 1)
91+
reverse(0, k - 1)
92+
reverse(k, n - 1)
8393
```
8494

8595
### **Java**
@@ -88,52 +98,107 @@ class Solution:
8898

8999
```java
90100
class Solution {
101+
private int[] nums;
102+
91103
public void rotate(int[] nums, int k) {
92-
if (nums == null) {
93-
return;
94-
}
104+
this.nums = nums;
95105
int n = nums.length;
96106
k %= n;
97-
if (n < 2 || k == 0) {
98-
return;
99-
}
100-
101-
rotate(nums, 0, n - 1);
102-
rotate(nums, 0, k - 1);
103-
rotate(nums, k, n - 1);
107+
reverse(0, n - 1);
108+
reverse(0, k - 1);
109+
reverse(k, n - 1);
104110
}
105111

106-
private void rotate(int[] nums, int i, int j) {
107-
while (i < j) {
112+
private void reverse(int i, int j) {
113+
for (; i < j; ++i, --j) {
108114
int t = nums[i];
109115
nums[i] = nums[j];
110116
nums[j] = t;
111-
++i;
112-
--j;
113117
}
114118
}
115119
}
116120
```
117121

118-
### **JavaScript**
122+
### **C++**
119123

120-
<!-- 这里可写当前语言的特殊实现逻辑 -->
124+
```cpp
125+
class Solution {
126+
public:
127+
void rotate(vector<int>& nums, int k) {
128+
int n = nums.size();
129+
k %= n;
130+
reverse(nums.begin(), nums.end());
131+
reverse(nums.begin(), nums.begin() + k);
132+
reverse(nums.begin() + k, nums.end());
133+
}
134+
};
135+
```
121136
122-
使用原生 API 将数组的 `k~n-1` 范围内的元素插入到前面
137+
### **Go**
123138
124-
```js
139+
```go
140+
func rotate(nums []int, k int) {
141+
n := len(nums)
142+
k %= n
143+
reverse := func(i, j int) {
144+
for ; i < j; i, j = i+1, j-1 {
145+
nums[i], nums[j] = nums[j], nums[i]
146+
}
147+
}
148+
reverse(0, n-1)
149+
reverse(0, k-1)
150+
reverse(k, n-1)
151+
}
152+
```
153+
154+
### **TypeScript**
155+
156+
```ts
125157
/**
126-
* @param {number[]} nums
127-
* @param {number} k
128-
* @return {void} Do not return anything, modify nums in-place instead.
158+
Do not return anything, modify nums in-place instead.
129159
*/
130-
var rotate = function (nums, k) {
131-
k %= nums.length;
132-
nums.splice(0, 0, ...nums.splice(-k, k));
133-
};
160+
function rotate(nums: number[], k: number): void {
161+
const n: number = nums.length;
162+
k %= n;
163+
const reverse = (i: number, j: number): void => {
164+
for (; i < j; ++i, --j) {
165+
const t: number = nums[i];
166+
nums[i] = nums[j];
167+
nums[j] = t;
168+
}
169+
};
170+
reverse(0, n - 1);
171+
reverse(0, k - 1);
172+
reverse(k, n - 1);
173+
}
134174
```
135175

136-
使用三次数组翻转 + 双指针实现翻转
176+
### **C#**
177+
178+
```cs
179+
public class Solution {
180+
private int[] nums;
181+
182+
public void Rotate(int[] nums, int k) {
183+
this.nums = nums;
184+
int n = nums.Length;
185+
k %= n;
186+
reverse(0, n - 1);
187+
reverse(0, k - 1);
188+
reverse(k, n - 1);
189+
}
190+
191+
private void reverse(int i, int j) {
192+
for (; i < j; ++i, --j) {
193+
int t = nums[i];
194+
nums[i] = nums[j];
195+
nums[j] = t;
196+
}
197+
}
198+
}
199+
```
200+
201+
### **JavaScript**
137202

138203
```js
139204
/**
@@ -142,43 +207,17 @@ var rotate = function (nums, k) {
142207
* @return {void} Do not return anything, modify nums in-place instead.
143208
*/
144209
var rotate = function (nums, k) {
145-
k %= nums.length;
146-
// 使用三次数组翻转
147-
reverse(nums, 0, nums.length - 1);
148-
reverse(nums, 0, k - 1);
149-
reverse(nums, k, nums.length - 1);
210+
const n = nums.length;
211+
k %= n;
212+
const reverse = (i, j) => {
213+
for (; i < j; ++i, --j) {
214+
[nums[i], nums[j]] = [nums[j], nums[i]];
215+
}
216+
};
217+
reverse(0, n - 1);
218+
reverse(0, k - 1);
219+
reverse(k, n - 1);
150220
};
151-
function reverse(nums, start, end) {
152-
// 双指针实现翻转
153-
while (start < end) {
154-
const temp = nums[start];
155-
nums[start] = nums[end];
156-
nums[end] = temp;
157-
start += 1;
158-
end -= 1;
159-
}
160-
}
161-
```
162-
163-
### **Go**
164-
165-
```go
166-
func rotate(nums []int, k int) {
167-
n := len(nums)
168-
k %= n
169-
170-
reverse(nums, 0, n-1)
171-
reverse(nums, 0, k-1)
172-
reverse(nums, k, n-1)
173-
}
174-
175-
func reverse(nums []int, i, j int) {
176-
for i < j {
177-
nums[i], nums[j] = nums[j], nums[i]
178-
i++
179-
j--
180-
}
181-
}
182221
```
183222

184223
### **Rust**
@@ -188,10 +227,6 @@ impl Solution {
188227
pub fn rotate(nums: &mut Vec<i32>, k: i32) {
189228
let n = nums.len();
190229
let k = k as usize % n;
191-
if n == 1 || k == 0 {
192-
return;
193-
}
194-
195230
nums.reverse();
196231
nums[..k].reverse();
197232
nums[k..].reverse();

0 commit comments

Comments
 (0)