Skip to content

Commit

Permalink
leetcode: Update 0189
Browse files Browse the repository at this point in the history
  • Loading branch information
XuShaohua committed Jun 27, 2024
1 parent 81376cd commit 27da855
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 45 deletions.
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
- [0136. 只出现一次的数字 Single Number](leetcode/0136.single-number/index.md)
- [0137. 只出现一次的数字II Single Number II](leetcode/0137.single-number-ii/index.md)
- [0167. 两数之和 II - 输入有序数组 Two Sum II - Input Array Is Sorted](leetcode/0167.two-sum-ii-input-array-is-sorted/index.md)
- [0189. 旋转数组 Rotate Array](leetcode/0189.rotate-array/index.md)
- [0191. 位1的个数 Number of 1 Bits](leetcode/0191.number-of-1-bits/index.md)
- [0201-0300](leetcode/by-id/0201-0300.md)
- [0217. 存在重复元素 Contains Duplicate](leetcode/0217.contains-duplicate/index.md)
Expand Down
2 changes: 1 addition & 1 deletion src/array/rotate.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
{{#include assets/rotate.rs:7:50}}
```

## 方法2: 使用数组反转
## 方法2: 三次反转法

操作过程如下:

Expand Down
20 changes: 19 additions & 1 deletion src/leetcode/0189.rotate-array/index.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
#
# 旋转数组 Rotate Array

[问题描述](https://leetcode.com/problems/rotate-array/)

## 三次反转法

操作过程如下:

1.`arr[k..n]` 进行反转
2.`arr[0..k]` 进行反转
3.`arr[..]` 进行反转

这个方法是在原地操作的, 其时间复杂度是 `O(n)`, 空间复杂度是 `O(1)`.

```rust
{{#include src/main.rs:31:49}}
```

## 参考

- [旋转数组](../../array/rotate.md)
48 changes: 5 additions & 43 deletions src/leetcode/0189.rotate-array/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub fn rotate1(nums: &mut Vec<i32>, k: i32) {
}
}

// 三次翻转.
// 三次反转法
pub fn rotate2(nums: &mut Vec<i32>, k: i32) {
// 检查边界条件
if nums.is_empty() || k <= 0 {
Expand All @@ -40,46 +40,14 @@ pub fn rotate2(nums: &mut Vec<i32>, k: i32) {
return;
}

// 第一步, 把所有元素做翻转.
// 第一步, 把所有元素做反转.
nums.reverse();

// 第二步, 找到右移的分界线 k, 把 [0..k] 做翻转; 把 [k..len] 做翻转
// 第二步, 找到右移的分界线 k, 把 [0..k] 做反转.
nums[0..k].reverse();
// 第三步, 把 [k..len] 做反转
nums[k..].reverse();
}

// 三次翻转, 但使用靠拢型双指针实现反转函数.
pub fn rotate3(nums: &mut Vec<i32>, k: i32) {
fn reverse_array(nums: &mut [i32], mut start: usize, mut end: usize) {
let mut temp;
while start < end {
// nums.swap(start, end);
temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start += 1;
end -= 1;
}
}

// 检查边界条件
if nums.is_empty() || k <= 0 {
return;
}
let len: usize = nums.len();
let k: usize = (k as usize) % len;
if k == 0 {
return;
}

// 第一步, 把所有元素做翻转.
reverse_array(nums, 0, len - 1);

// 第二步, 找到右移的分界线 k, 把 [0..k] 做翻转; 把 [k..len] 做翻转
reverse_array(nums, 0, k - 1);
reverse_array(nums, k, len - 1);
}

pub type SolutionFn = fn(&mut Vec<i32>, i32);

fn check_solution(func: SolutionFn) {
Expand All @@ -97,12 +65,11 @@ fn check_solution(func: SolutionFn) {
fn main() {
check_solution(rotate1);
check_solution(rotate2);
check_solution(rotate3);
}

#[cfg(test)]
mod tests {
use super::{check_solution, rotate1, rotate2, rotate3};
use super::{check_solution, rotate1, rotate2};

#[test]
fn test_rotate1() {
Expand All @@ -113,9 +80,4 @@ mod tests {
fn test_rotate2() {
check_solution(rotate2);
}

#[test]
fn test_rotate3() {
check_solution(rotate3);
}
}

0 comments on commit 27da855

Please sign in to comment.