From 3b0816904356e114199c32520164560093d96039 Mon Sep 17 00:00:00 2001 From: krahets Date: Fri, 14 Mar 2025 17:51:07 +0800 Subject: [PATCH] deploy --- chapter_array_and_linkedlist/list/index.html | 201 +++++++------ chapter_backtracking/summary/index.html | 2 +- chapter_hashing/hash_algorithm/index.html | 4 +- chapter_hashing/hash_collision/index.html | 174 ++++++------ chapter_sorting/counting_sort/index.html | 26 +- chapter_stack_and_queue/deque/index.html | 24 +- chapter_stack_and_queue/queue/index.html | 24 +- chapter_stack_and_queue/stack/index.html | 50 ++-- en/chapter_backtracking/index.html | 4 +- .../index.html | 2 +- .../build_binary_tree_problem/index.html | 74 ++--- .../divide_and_conquer/index.html | 74 ++--- .../hanota_problem/index.html | 56 ++-- en/chapter_divide_and_conquer/index.html | 4 +- .../summary/index.html | 18 +- en/chapter_dynamic_programming/index.html | 2 +- en/chapter_heap/heap/index.html | 266 +++++++++--------- en/chapter_heap/index.html | 4 +- .../binary_search_edge/index.html | 42 +-- .../binary_search_insertion/index.html | 34 +-- en/chapter_sorting/bubble_sort/index.html | 24 +- en/chapter_sorting/bucket_sort/index.html | 22 +- en/chapter_sorting/counting_sort/index.html | 20 +- en/chapter_sorting/heap_sort/index.html | 14 +- en/chapter_sorting/index.html | 2 +- en/chapter_sorting/insertion_sort/index.html | 20 +- en/chapter_sorting/merge_sort/index.html | 20 +- en/chapter_sorting/quick_sort/index.html | 37 +-- en/chapter_sorting/radix_sort/index.html | 14 +- en/chapter_sorting/selection_sort/index.html | 8 +- en/chapter_sorting/summary/index.html | 12 +- en/search/search_index.json | 2 +- en/sitemap.xml | 210 +++++++------- en/sitemap.xml.gz | Bin 1007 -> 1008 bytes search/search_index.json | 2 +- sitemap.xml | 212 +++++++------- sitemap.xml.gz | Bin 1011 -> 1011 bytes zh-hant/sitemap.xml | 210 +++++++------- zh-hant/sitemap.xml.gz | Bin 1010 -> 1011 bytes 39 files changed, 956 insertions(+), 958 deletions(-) diff --git a/chapter_array_and_linkedlist/list/index.html b/chapter_array_and_linkedlist/list/index.html index d72282f50..e0be92f8b 100644 --- a/chapter_array_and_linkedlist/list/index.html +++ b/chapter_array_and_linkedlist/list/index.html @@ -5548,107 +5548,106 @@ impl MyList { /* 构造方法 */ pub fn new(capacity: usize) -> Self { - let mut vec = Vec::new(); - vec.resize(capacity, 0); - Self { - arr: vec, - capacity, - size: 0, - extend_ratio: 2, - } - } - - /* 获取列表长度(当前元素数量)*/ - pub fn size(&self) -> usize { - return self.size; - } - - /* 获取列表容量 */ - pub fn capacity(&self) -> usize { - return self.capacity; - } - - /* 访问元素 */ - pub fn get(&self, index: usize) -> i32 { - // 索引如果越界,则抛出异常,下同 - if index >= self.size { - panic!("索引越界") - }; - return self.arr[index]; - } - - /* 更新元素 */ - pub fn set(&mut self, index: usize, num: i32) { - if index >= self.size { - panic!("索引越界") - }; - self.arr[index] = num; - } - - /* 在尾部添加元素 */ - pub fn add(&mut self, num: i32) { - // 元素数量超出容量时,触发扩容机制 - if self.size == self.capacity() { - self.extend_capacity(); - } - self.arr[self.size] = num; - // 更新元素数量 - self.size += 1; - } - - /* 在中间插入元素 */ - pub fn insert(&mut self, index: usize, num: i32) { - if index >= self.size() { - panic!("索引越界") - }; - // 元素数量超出容量时,触发扩容机制 - if self.size == self.capacity() { - self.extend_capacity(); - } - // 将索引 index 以及之后的元素都向后移动一位 - for j in (index..self.size).rev() { - self.arr[j + 1] = self.arr[j]; - } - self.arr[index] = num; - // 更新元素数量 - self.size += 1; - } - - /* 删除元素 */ - pub fn remove(&mut self, index: usize) -> i32 { - if index >= self.size() { - panic!("索引越界") - }; - let num = self.arr[index]; - // 将将索引 index 之后的元素都向前移动一位 - for j in (index..self.size - 1) { - self.arr[j] = self.arr[j + 1]; - } - // 更新元素数量 - self.size -= 1; - // 返回被删除的元素 - return num; - } - - /* 列表扩容 */ - pub fn extend_capacity(&mut self) { - // 新建一个长度为原数组 extend_ratio 倍的新数组,并将原数组复制到新数组 - let new_capacity = self.capacity * self.extend_ratio; - self.arr.resize(new_capacity, 0); - // 更新列表容量 - self.capacity = new_capacity; - } - - /* 将列表转换为数组 */ - pub fn to_array(&mut self) -> Vec<i32> { - // 仅转换有效长度范围内的列表元素 - let mut arr = Vec::new(); - for i in 0..self.size { - arr.push(self.get(i)); - } - arr - } -} + let mut vec = vec![0; capacity]; + Self { + arr: vec, + capacity, + size: 0, + extend_ratio: 2, + } + } + + /* 获取列表长度(当前元素数量)*/ + pub fn size(&self) -> usize { + return self.size; + } + + /* 获取列表容量 */ + pub fn capacity(&self) -> usize { + return self.capacity; + } + + /* 访问元素 */ + pub fn get(&self, index: usize) -> i32 { + // 索引如果越界,则抛出异常,下同 + if index >= self.size { + panic!("索引越界") + }; + return self.arr[index]; + } + + /* 更新元素 */ + pub fn set(&mut self, index: usize, num: i32) { + if index >= self.size { + panic!("索引越界") + }; + self.arr[index] = num; + } + + /* 在尾部添加元素 */ + pub fn add(&mut self, num: i32) { + // 元素数量超出容量时,触发扩容机制 + if self.size == self.capacity() { + self.extend_capacity(); + } + self.arr[self.size] = num; + // 更新元素数量 + self.size += 1; + } + + /* 在中间插入元素 */ + pub fn insert(&mut self, index: usize, num: i32) { + if index >= self.size() { + panic!("索引越界") + }; + // 元素数量超出容量时,触发扩容机制 + if self.size == self.capacity() { + self.extend_capacity(); + } + // 将索引 index 以及之后的元素都向后移动一位 + for j in (index..self.size).rev() { + self.arr[j + 1] = self.arr[j]; + } + self.arr[index] = num; + // 更新元素数量 + self.size += 1; + } + + /* 删除元素 */ + pub fn remove(&mut self, index: usize) -> i32 { + if index >= self.size() { + panic!("索引越界") + }; + let num = self.arr[index]; + // 将将索引 index 之后的元素都向前移动一位 + for j in index..self.size - 1 { + self.arr[j] = self.arr[j + 1]; + } + // 更新元素数量 + self.size -= 1; + // 返回被删除的元素 + return num; + } + + /* 列表扩容 */ + pub fn extend_capacity(&mut self) { + // 新建一个长度为原数组 extend_ratio 倍的新数组,并将原数组复制到新数组 + let new_capacity = self.capacity * self.extend_ratio; + self.arr.resize(new_capacity, 0); + // 更新列表容量 + self.capacity = new_capacity; + } + + /* 将列表转换为数组 */ + pub fn to_array(&self) -> Vec<i32> { + // 仅转换有效长度范围内的列表元素 + let mut arr = Vec::new(); + for i in 0..self.size { + arr.push(self.get(i)); + } + arr + } +}
diff --git a/chapter_backtracking/summary/index.html b/chapter_backtracking/summary/index.html index aa4dddcd3..1c54740b2 100644 --- a/chapter_backtracking/summary/index.html +++ b/chapter_backtracking/summary/index.html @@ -3660,7 +3660,7 @@
  • 子集和问题的目标是在给定集合中找到和为目标值的所有子集。集合不区分元素顺序,而搜索过程会输出所有顺序的结果,产生重复子集。我们在回溯前将数据进行排序,并设置一个变量来指示每一轮的遍历起始点,从而将生成重复子集的搜索分支进行剪枝。
  • 对于子集和问题,数组中的相等元素会产生重复集合。我们利用数组已排序的前置条件,通过判断相邻元素是否相等实现剪枝,从而确保相等元素在每轮中只能被选中一次。
  • \(n\) 皇后问题旨在寻找将 \(n\) 个皇后放置到 \(n \times n\) 尺寸棋盘上的方案,要求所有皇后两两之间无法攻击对方。该问题的约束条件有行约束、列约束、主对角线和次对角线约束。为满足行约束,我们采用按行放置的策略,保证每一行放置一个皇后。
  • -
  • 列约束和对角线约束的处理方式类似。对于列约束,我们利用一个数组来记录每一列是否有皇后,从而指示选中的格子是否合法。对于对角线约束,我们借助两个数组来分别记录该主、次对角线上是否存在皇后;难点在于找处在到同一主(副)对角线上格子满足的行列索引规律。
  • +
  • 列约束和对角线约束的处理方式类似。对于列约束,我们利用一个数组来记录每一列是否有皇后,从而指示选中的格子是否合法。对于对角线约束,我们借助两个数组来分别记录该主、次对角线上是否存在皇后;难点在于找出处在同一主(副)对角线上的格子所满足的行列索引规律。
  • 2.   Q & A

    Q:怎么理解回溯和递归的关系?

    diff --git a/chapter_hashing/hash_algorithm/index.html b/chapter_hashing/hash_algorithm/index.html index e58c0209a..e3538f655 100644 --- a/chapter_hashing/hash_algorithm/index.html +++ b/chapter_hashing/hash_algorithm/index.html @@ -4012,7 +4012,7 @@ for (const c of key) { hash ^= c.charCodeAt(0); } - return hash & MODULUS; + return hash % MODULUS; } /* 旋转哈希 */ @@ -4054,7 +4054,7 @@ for (const c of key) { hash ^= c.charCodeAt(0); } - return hash & MODULUS; + return hash % MODULUS; } /* 旋转哈希 */ diff --git a/chapter_hashing/hash_collision/index.html b/chapter_hashing/hash_collision/index.html index 87acebb62..a372e2116 100644 --- a/chapter_hashing/hash_collision/index.html +++ b/chapter_hashing/hash_collision/index.html @@ -4731,10 +4731,10 @@
    hash_map_chaining.rs
    /* 链式地址哈希表 */
     struct HashMapChaining {
    -    size: i32,
    -    capacity: i32,
    +    size: usize,
    +    capacity: usize,
         load_thres: f32,
    -    extend_ratio: i32,
    +    extend_ratio: usize,
         buckets: Vec<Vec<Pair>>,
     }
     
    @@ -4752,7 +4752,7 @@
     
         /* 哈希函数 */
         fn hash_func(&self, key: i32) -> usize {
    -        key as usize % self.capacity as usize
    +        key as usize % self.capacity
         }
     
         /* 负载因子 */
    @@ -4763,91 +4763,87 @@
         /* 删除操作 */
         fn remove(&mut self, key: i32) -> Option<String> {
             let index = self.hash_func(key);
    -        let bucket = &mut self.buckets[index];
    -
    -        // 遍历桶,从中删除键值对
    -        for i in 0..bucket.len() {
    -            if bucket[i].key == key {
    -                let pair = bucket.remove(i);
    -                self.size -= 1;
    -                return Some(pair.val);
    -            }
    -        }
    -
    -        // 若未找到 key ,则返回 None
    -        None
    -    }
    -
    -    /* 扩容哈希表 */
    -    fn extend(&mut self) {
    -        // 暂存原哈希表
    -        let buckets_tmp = std::mem::replace(&mut self.buckets, vec![]);
    -
    -        // 初始化扩容后的新哈希表
    -        self.capacity *= self.extend_ratio;
    -        self.buckets = vec![Vec::new(); self.capacity as usize];
    -        self.size = 0;
    -
    -        // 将键值对从原哈希表搬运至新哈希表
    -        for bucket in buckets_tmp {
    -            for pair in bucket {
    -                self.put(pair.key, pair.val);
    -            }
    -        }
    -    }
    -
    -    /* 打印哈希表 */
    -    fn print(&self) {
    -        for bucket in &self.buckets {
    -            let mut res = Vec::new();
    -            for pair in bucket {
    -                res.push(format!("{} -> {}", pair.key, pair.val));
    -            }
    -            println!("{:?}", res);
    -        }
    -    }
    -
    -    /* 添加操作 */
    -    fn put(&mut self, key: i32, val: String) {
    -        // 当负载因子超过阈值时,执行扩容
    -        if self.load_factor() > self.load_thres {
    -            self.extend();
    -        }
    -
    -        let index = self.hash_func(key);
    -        let bucket = &mut self.buckets[index];
    -
    -        // 遍历桶,若遇到指定 key ,则更新对应 val 并返回
    -        for pair in bucket {
    -            if pair.key == key {
    -                pair.val = val;
    -                return;
    -            }
    -        }
    -        let bucket = &mut self.buckets[index];
    -
    -        // 若无该 key ,则将键值对添加至尾部
    -        let pair = Pair { key, val };
    -        bucket.push(pair);
    -        self.size += 1;
    -    }
    -
    -    /* 查询操作 */
    -    fn get(&self, key: i32) -> Option<&str> {
    -        let index = self.hash_func(key);
    -        let bucket = &self.buckets[index];
    -
    -        // 遍历桶,若找到 key ,则返回对应 val
    -        for pair in bucket {
    -            if pair.key == key {
    -                return Some(&pair.val);
    -            }
    -        }
    -
    -        // 若未找到 key ,则返回 None
    -        None
    -    }
    -}
    +
    +        // 遍历桶,从中删除键值对
    +        for (i, p) in self.buckets[index].iter_mut().enumerate() {
    +            if p.key == key {
    +                let pair = self.buckets[index].remove(i);
    +                self.size -= 1;
    +                return Some(pair.val);
    +            }
    +        }
    +
    +        // 若未找到 key ,则返回 None
    +        None
    +    }
    +
    +    /* 扩容哈希表 */
    +    fn extend(&mut self) {
    +        // 暂存原哈希表
    +        let buckets_tmp = std::mem::take(&mut self.buckets);
    +
    +        // 初始化扩容后的新哈希表
    +        self.capacity *= self.extend_ratio;
    +        self.buckets = vec![Vec::new(); self.capacity as usize];
    +        self.size = 0;
    +
    +        // 将键值对从原哈希表搬运至新哈希表
    +        for bucket in buckets_tmp {
    +            for pair in bucket {
    +                self.put(pair.key, pair.val);
    +            }
    +        }
    +    }
    +
    +    /* 打印哈希表 */
    +    fn print(&self) {
    +        for bucket in &self.buckets {
    +            let mut res = Vec::new();
    +            for pair in bucket {
    +                res.push(format!("{} -> {}", pair.key, pair.val));
    +            }
    +            println!("{:?}", res);
    +        }
    +    }
    +
    +    /* 添加操作 */
    +    fn put(&mut self, key: i32, val: String) {
    +        // 当负载因子超过阈值时,执行扩容
    +        if self.load_factor() > self.load_thres {
    +            self.extend();
    +        }
    +
    +        let index = self.hash_func(key);
    +
    +        // 遍历桶,若遇到指定 key ,则更新对应 val 并返回
    +        for pair in self.buckets[index].iter_mut() {
    +            if pair.key == key {
    +                pair.val = val;
    +                return;
    +            }
    +        }
    +
    +        // 若无该 key ,则将键值对添加至尾部
    +        let pair = Pair { key, val };
    +        self.buckets[index].push(pair);
    +        self.size += 1;
    +    }
    +
    +    /* 查询操作 */
    +    fn get(&self, key: i32) -> Option<&str> {
    +        let index = self.hash_func(key);
    +
    +        // 遍历桶,若找到 key ,则返回对应 val
    +        for pair in self.buckets[index].iter() {
    +            if pair.key == key {
    +                return Some(&pair.val);
    +            }
    +        }
    +
    +        // 若未找到 key ,则返回 None
    +        None
    +    }
    +}
     
    diff --git a/chapter_sorting/counting_sort/index.html b/chapter_sorting/counting_sort/index.html index 64fa6c438..8287258ad 100644 --- a/chapter_sorting/counting_sort/index.html +++ b/chapter_sorting/counting_sort/index.html @@ -3704,20 +3704,18 @@ """计数排序""" # 简单实现,无法用于排序对象 # 1. 统计数组最大元素 m - m = 0 - for num in nums: - m = max(m, num) - # 2. 统计各数字的出现次数 - # counter[num] 代表 num 的出现次数 - counter = [0] * (m + 1) - for num in nums: - counter[num] += 1 - # 3. 遍历 counter ,将各元素填入原数组 nums - i = 0 - for num in range(m + 1): - for _ in range(counter[num]): - nums[i] = num - i += 1 + m = max(nums) + # 2. 统计各数字的出现次数 + # counter[num] 代表 num 的出现次数 + counter = [0] * (m + 1) + for num in nums: + counter[num] += 1 + # 3. 遍历 counter ,将各元素填入原数组 nums + i = 0 + for num in range(m + 1): + for _ in range(counter[num]): + nums[i] = num + i += 1
    diff --git a/chapter_stack_and_queue/deque/index.html b/chapter_stack_and_queue/deque/index.html index ff6b5bdff..be6a86669 100644 --- a/chapter_stack_and_queue/deque/index.html +++ b/chapter_stack_and_queue/deque/index.html @@ -5370,7 +5370,7 @@ } } self.que_size -= 1; // 更新队列长度 - Rc::try_unwrap(old_front).ok().unwrap().into_inner().val + old_front.borrow().val }) } // 队尾出队操作 @@ -5386,7 +5386,7 @@ } } self.que_size -= 1; // 更新队列长度 - Rc::try_unwrap(old_rear).ok().unwrap().into_inner().val + old_rear.borrow().val }) } } @@ -5413,14 +5413,18 @@ /* 返回数组用于打印 */ pub fn to_array(&self, head: Option<&Rc<RefCell<ListNode<T>>>>) -> Vec<T> { - if let Some(node) = head { - let mut nums = self.to_array(node.borrow().next.as_ref()); - nums.insert(0, node.borrow().val); - return nums; - } - return Vec::new(); - } -} + let mut res: Vec<T> = Vec::new(); + fn recur<T: Copy>(cur: Option<&Rc<RefCell<ListNode<T>>>>, res: &mut Vec<T>) { + if let Some(cur) = cur { + res.push(cur.borrow().val); + recur(cur.borrow().next.as_ref(), res); + } + } + + recur(head, &mut res); + res + } +}
    diff --git a/chapter_stack_and_queue/queue/index.html b/chapter_stack_and_queue/queue/index.html index 0810a9690..6bb0d763b 100644 --- a/chapter_stack_and_queue/queue/index.html +++ b/chapter_stack_and_queue/queue/index.html @@ -4750,7 +4750,7 @@ } } self.que_size -= 1; - Rc::try_unwrap(old_front).ok().unwrap().into_inner().val + old_front.borrow().val }) } @@ -4761,14 +4761,20 @@ /* 将链表转化为 Array 并返回 */ pub fn to_array(&self, head: Option<&Rc<RefCell<ListNode<T>>>>) -> Vec<T> { - if let Some(node) = head { - let mut nums = self.to_array(node.borrow().next.as_ref()); - nums.insert(0, node.borrow().val); - return nums; - } - return Vec::new(); - } -} + let mut res: Vec<T> = Vec::new(); + + fn recur<T: Copy>(cur: Option<&Rc<RefCell<ListNode<T>>>>, res: &mut Vec<T>) { + if let Some(cur) = cur { + res.push(cur.borrow().val); + recur(cur.borrow().next.as_ref(), res); + } + } + + recur(head, &mut res); + + res + } +}
    diff --git a/chapter_stack_and_queue/stack/index.html b/chapter_stack_and_queue/stack/index.html index 90d737713..01971203d 100644 --- a/chapter_stack_and_queue/stack/index.html +++ b/chapter_stack_and_queue/stack/index.html @@ -4659,34 +4659,28 @@ /* 出栈 */ pub fn pop(&mut self) -> Option<T> { self.stack_peek.take().map(|old_head| { - match old_head.borrow_mut().next.take() { - Some(new_head) => { - self.stack_peek = Some(new_head); - } - None => { - self.stack_peek = None; - } - } - self.stk_size -= 1; - Rc::try_unwrap(old_head).ok().unwrap().into_inner().val - }) - } - - /* 访问栈顶元素 */ - pub fn peek(&self) -> Option<&Rc<RefCell<ListNode<T>>>> { - self.stack_peek.as_ref() - } - - /* 将 List 转化为 Array 并返回 */ - pub fn to_array(&self, head: Option<&Rc<RefCell<ListNode<T>>>>) -> Vec<T> { - if let Some(node) = head { - let mut nums = self.to_array(node.borrow().next.as_ref()); - nums.push(node.borrow().val); - return nums; - } - return Vec::new(); - } -} + self.stack_peek = old_head.borrow_mut().next.take(); + self.stk_size -= 1; + + old_head.borrow().val + }) + } + + /* 访问栈顶元素 */ + pub fn peek(&self) -> Option<&Rc<RefCell<ListNode<T>>>> { + self.stack_peek.as_ref() + } + + /* 将 List 转化为 Array 并返回 */ + pub fn to_array(&self, head: Option<&Rc<RefCell<ListNode<T>>>>) -> Vec<T> { + if let Some(node) = head { + let mut nums = self.to_array(node.borrow().next.as_ref()); + nums.push(node.borrow().val); + return nums; + } + return Vec::new(); + } +}
    diff --git a/en/chapter_backtracking/index.html b/en/chapter_backtracking/index.html index 4f4e34116..4f272ef77 100644 --- a/en/chapter_backtracking/index.html +++ b/en/chapter_backtracking/index.html @@ -3520,8 +3520,8 @@

    Backtracking

    Abstract

    -

    Like explorers in a maze, we may encounter difficulties on our path forward.

    -

    The power of backtracking allows us to start over, keep trying, and eventually find the exit to the light.

    +

    Like explorers in a maze, we may encounter obstacles on our path forward.

    +

    The power of backtracking lets us begin anew, keep trying, and eventually find the exit leading to the light.

    Chapter contents