diff --git a/src/SUMMARY.md b/src/SUMMARY.md
index cc3f6fb8..30210a56 100644
--- a/src/SUMMARY.md
+++ b/src/SUMMARY.md
@@ -48,6 +48,7 @@
- [第二部分: 算法](algs/index.md)
- [分析算法](algs-analysis/index.md)
- [排序 Sorting](sorting/index.md)
+ - [排序相关的问题列表](leetcode/tags/sorting.md)
- [查找](searching/index.md)
- [二分查找 Binary Search](searching/binary-search/index.md)
- [二分查找相关的问题列表](leetcode/tags/binary-search.md)
@@ -90,6 +91,7 @@
- [链表](leetcode/tags/linked-list.md)
- [数学](leetcode/tags/math.md)
- [滑动窗口](leetcode/tags/sliding-window.md)
+ - [排序](leetcode/tags/sorting.md)
- [栈](leetcode/tags/stack.md)
- [字符串](leetcode/tags/string.md)
- [双指针](leetcode/tags/two-pointers.md)
@@ -101,6 +103,7 @@
- [0015. 三数之和 3Sum](leetcode/0015.3sum/index.md)
- [0026. 删除有序数组中的重复项 Remove Duplicates from Sorted Array](leetcode/0026.remove-duplicates-from-sorted-array/index.md)
- [0067. 二进制求和 Add Binary](leetcode/0067.add-binary/index.md)
+ - [0075. 颜色分类 Sort Colors](leetcode/0075.sort-colors/index.md)
- [0080. 删除排序数组中的重复项 II Remove Duplicates from Sorted Array II](leetcode/0080.remove-duplicates-from-sorted-array-ii/index.md)
- [0088. 合并两个有序数组 Merge Sorted Array](leetcode/0088.merge-sorted-array/index.md)
- [0101-0200](leetcode/orders/0101-0200.md)
diff --git a/src/leetcode/0075.sort-colors/assets/three-pointers.drawio b/src/leetcode/0075.sort-colors/assets/three-pointers.drawio
new file mode 100644
index 00000000..c6fdf921
--- /dev/null
+++ b/src/leetcode/0075.sort-colors/assets/three-pointers.drawio
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/leetcode/0075.sort-colors/index.md b/src/leetcode/0075.sort-colors/index.md
new file mode 100644
index 00000000..69c2287b
--- /dev/null
+++ b/src/leetcode/0075.sort-colors/index.md
@@ -0,0 +1,19 @@
+# 0075. 颜色分类 Sort Colors
+
+[问题描述](../problems/0075.sort-colors/content.html)
+
+## 靠拢型双指针
+
+靠拢型双指针是一种常用方法, 这个解法是它的变体, 叫[DNF](../../two-pointers/close-up.md).
+
+```rust
+{{#include src/main.rs:7:40 }}
+```
+
+## 排序法
+
+各种常见的排序算法都可以, 比如括入排序, 选择排序. 因为这毕竟是一个排序题.
+
+```rust
+{{#include src/main.rs:47:56 }}
+```
\ No newline at end of file
diff --git a/src/leetcode/0075.sort-colors/src/main.rs b/src/leetcode/0075.sort-colors/src/main.rs
index 9bb5c525..b9d80cdc 100644
--- a/src/leetcode/0075.sort-colors/src/main.rs
+++ b/src/leetcode/0075.sort-colors/src/main.rs
@@ -4,19 +4,32 @@
#![allow(clippy::ptr_arg)]
-pub fn sort_colors(nums: &mut Vec) {
- let mut low = 0;
+// 靠拢型双指针
+// Dutch National Flag, DNF
+// three-way partition
+pub fn sort_colors1(nums: &mut Vec) {
+ assert!(!nums.is_empty());
+
+ // 双指针的变形, 三指针
+ // left 用于指向数组中为0的元素的右侧
+ let mut left = 0;
+ // mid 用于遍历数组
let mut mid = 0;
- let mut high = nums.len() - 1;
- while mid <= high {
+ // right 用于指向数组中为2的元素的左侧
+ let mut right = nums.len() - 1;
+
+ // 遍历数组
+ while mid <= right {
if nums[mid] == 0 {
- nums.swap(mid, low);
- low += 1;
+ nums.swap(mid, left);
mid += 1;
+ // 左边的指针往右移一下
+ left += 1;
} else if nums[mid] == 2 {
- nums.swap(mid, high);
- if high > 0 {
- high -= 1;
+ nums.swap(mid, right);
+ // 右边的指针往左移一下
+ if right > 0 {
+ right -= 1;
} else {
break;
}
@@ -26,20 +39,102 @@ pub fn sort_colors(nums: &mut Vec) {
}
}
-fn check_solution() {
+// 调用数组的排序方法, 这个不符合要求.
+pub fn sort_colors2(nums: &mut Vec) {
+ nums.sort();
+}
+
+// 选择排序 Selection Sort
+pub fn sort_colors3(nums: &mut Vec) {
+ for i in 0..(nums.len() - 1) {
+ for j in i..nums.len() {
+ if nums[i] > nums[j] {
+ nums.swap(i, j);
+ }
+ }
+ }
+}
+
+// 插入排序 Insertion Sort
+pub fn sort_colors4(nums: &mut Vec) {
+ for i in 1..nums.len() {
+ let mut j = i;
+ while j > 0 && nums[j - 1] > nums[j] {
+ nums.swap(j - 1, j);
+ j -= 1;
+ }
+ }
+}
+
+// 冒泡排序 Bubble Sort
+pub fn sort_colors5(nums: &mut Vec) {
+ for i in 0..(nums.len() - 1) {
+ let mut swapped = false;
+ for j in 0..(nums.len() - 1 - i) {
+ if nums[j] > nums[j + 1] {
+ nums.swap(j, j + 1);
+ swapped = true;
+ }
+ }
+
+ if !swapped {
+ break;
+ }
+ }
+}
+
+pub type SolutionFn = fn(&mut Vec);
+
+fn check_solution(func: SolutionFn) {
let mut nums = vec![2, 0, 2, 1, 1, 0];
- sort_colors(&mut nums);
+ func(&mut nums);
assert_eq!(&nums, &[0, 0, 1, 1, 2, 2]);
let mut nums = vec![2, 2];
- sort_colors(&mut nums);
+ func(&mut nums);
assert_eq!(&nums, &[2, 2]);
let mut nums = vec![2];
- sort_colors(&mut nums);
+ func(&mut nums);
assert_eq!(&nums, &[2]);
}
fn main() {
- check_solution();
+ check_solution(sort_colors1);
+ check_solution(sort_colors2);
+ check_solution(sort_colors3);
+ check_solution(sort_colors4);
+ check_solution(sort_colors5);
+}
+
+#[cfg(test)]
+mod tests {
+ use super::{
+ check_solution, sort_colors1, sort_colors2, sort_colors3, sort_colors4, sort_colors5,
+ };
+
+ #[test]
+ fn test_sort_colors1() {
+ check_solution(sort_colors1);
+ }
+
+ #[test]
+ fn test_sort_colors2() {
+ check_solution(sort_colors2);
+ }
+
+ #[test]
+ fn test_sort_colors3() {
+ check_solution(sort_colors3);
+ }
+
+ #[test]
+ fn test_sort_colors4() {
+ check_solution(sort_colors4);
+ }
+
+ #[test]
+ fn test_sort_colors5() {
+ check_solution(sort_colors5);
+ }
}
diff --git a/src/leetcode/tags/sorting.md b/src/leetcode/tags/sorting.md
new file mode 100644
index 00000000..b3489d9d
--- /dev/null
+++ b/src/leetcode/tags/sorting.md
@@ -0,0 +1,9 @@
+# 排序
+
+## 简单
+
+## 中等
+
+1. [0075. 颜色分类 Sort Colors](../0075.sort-colors/index.md)
+
+## 困难
\ No newline at end of file
diff --git a/src/leetcode/tags/two-pointers.md b/src/leetcode/tags/two-pointers.md
index aa02fd81..6907ee76 100644
--- a/src/leetcode/tags/two-pointers.md
+++ b/src/leetcode/tags/two-pointers.md
@@ -22,16 +22,16 @@ TODO:
1. [0011. 盛最多水的容器 Container With Most Water](../0011.container-with-most-water/index.md)
2. [0015. 三数之和 3Sum](../0015.3sum/index.md)
-3. [0080. 删除排序数组中的重复项 II Remove Duplicates from Sorted Array II](../0080.remove-duplicates-from-sorted-array-ii/index.md)
-4. [0167. 两数之和 II - 输入有序数组 Two Sum II - Input Array Is Sorted](../0167.two-sum-ii-input-array-is-sorted/index.md)
-5. [0532.数组中的数对 K-diff Pairs in an Array](../0532.k-diff-pairs-in-an-array/index.md)
+3. [0075. 颜色分类 Sort Colors](../0075.sort-colors/index.md)
+4. [0080. 删除排序数组中的重复项 II Remove Duplicates from Sorted Array II](../0080.remove-duplicates-from-sorted-array-ii/index.md)
+5. [0167. 两数之和 II - 输入有序数组 Two Sum II - Input Array Is Sorted](../0167.two-sum-ii-input-array-is-sorted/index.md)
+6. [0532.数组中的数对 K-diff Pairs in an Array](../0532.k-diff-pairs-in-an-array/index.md)
TODO:
1. [31. 下一个排列](https://leetcode.com/problems/next-permutation)
-2. [75. 颜色分类](https://leetcode.com/problems/sort-colors)
-3. [142. 环形链表 II](https://leetcode.com/problems/linked-list-cycle-ii)
-4. [443. 压缩字符串](https://leetcode.com/problems/string-compression)
-5. [524. 通过删除字母匹配到字典里最长单词](https://leetcode.com/problems/longest-word-in-dictionary-through-deleting)
-6. [986. 区间列表的交集](https://leetcode.com/problems/interval-list-intersections)
-7. [1498. 满足条件的子序列数目](https://leetcode.com/problems/number-of-subsequences-that-satisfy-the-given-sum-condition)
+2. [142. 环形链表 II](https://leetcode.com/problems/linked-list-cycle-ii)
+3. [443. 压缩字符串](https://leetcode.com/problems/string-compression)
+4. [524. 通过删除字母匹配到字典里最长单词](https://leetcode.com/problems/longest-word-in-dictionary-through-deleting)
+5. [986. 区间列表的交集](https://leetcode.com/problems/interval-list-intersections)
+6. [1498. 满足条件的子序列数目](https://leetcode.com/problems/number-of-subsequences-that-satisfy-the-given-sum-condition)
diff --git a/src/two-pointers/assets/Flag_of_the_Netherlands.svg b/src/two-pointers/assets/Flag_of_the_Netherlands.svg
new file mode 100644
index 00000000..d17659fa
--- /dev/null
+++ b/src/two-pointers/assets/Flag_of_the_Netherlands.svg
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/src/two-pointers/assets/sort-colors.rs b/src/two-pointers/assets/sort-colors.rs
new file mode 120000
index 00000000..e1f0a79b
--- /dev/null
+++ b/src/two-pointers/assets/sort-colors.rs
@@ -0,0 +1 @@
+../../leetcode/0075.sort-colors/src/main.rs
\ No newline at end of file
diff --git a/src/two-pointers/close-up.md b/src/two-pointers/close-up.md
index 3ff68578..2025470c 100644
--- a/src/two-pointers/close-up.md
+++ b/src/two-pointers/close-up.md
@@ -11,6 +11,15 @@
- 根据题目要求, 选中左右两个指针中的一个, 往中间靠靠拢 (`left += 1` 或者 `right -= 1`, 另一个指针不动
- 直到循环中止
+## Dutch National Flag, DNF
+
+这是上面方法的一个变形, 可以查看问题 [0075. 颜色分类 Sort Colors](../leetcode/0075.sort-colors/index.md),
+这个方法用于实现三路分区 (three-way partition).
+
+![The Dutch national flag](assets/Flag_of_the_Netherlands.svg)
+
+访问 [wikipedia](https://en.wikipedia.org/wiki/Dutch_national_flag_problem) 查看对应的介绍.
+
## 相关问题
- [0011. 盛最多水的容器 Container With Most Water](../../leetcode/0011.container-with-most-water/index.md)