This commit is contained in:
krahets
2025-03-20 22:54:57 +08:00
parent e81bc45c43
commit 5286e8bbc2
11 changed files with 79 additions and 78 deletions
@@ -1963,8 +1963,7 @@ comments: true
impl MyList {
/* 建構子 */
pub fn new(capacity: usize) -> Self {
let mut vec = Vec::new();
vec.resize(capacity, 0);
let mut vec = vec![0; capacity];
Self {
arr: vec,
capacity,
@@ -2036,7 +2035,7 @@ comments: true
};
let num = self.arr[index];
// 將將索引 index 之後的元素都向前移動一位
for j in (index..self.size - 1) {
for j in index..self.size - 1 {
self.arr[j] = self.arr[j + 1];
}
// 更新元素數量
@@ -2055,7 +2054,7 @@ comments: true
}
/* 將串列轉換為陣列 */
pub fn to_array(&mut self) -> Vec<i32> {
pub fn to_array(&self) -> Vec<i32> {
// 僅轉換有效長度範圍內的串列元素
let mut arr = Vec::new();
for i in 0..self.size {
+1 -1
View File
@@ -15,7 +15,7 @@ comments: true
- 子集和問題的目標是在給定集合中找到和為目標值的所有子集。集合不區分元素順序,而搜尋過程會輸出所有順序的結果,產生重複子集。我們在回溯前將資料進行排序,並設定一個變數來指示每一輪的走訪起始點,從而將生成重複子集的搜尋分支進行剪枝。
- 對於子集和問題,陣列中的相等元素會產生重複集合。我們利用陣列已排序的前置條件,透過判斷相鄰元素是否相等實現剪枝,從而確保相等元素在每輪中只能被選中一次。
- $n$ 皇后問題旨在尋找將 $n$ 個皇后放置到 $n \times n$ 尺寸棋盤上的方案,要求所有皇后兩兩之間無法攻擊對方。該問題的約束條件有行約束、列約束、主對角線和次對角線約束。為滿足行約束,我們採用按行放置的策略,保證每一行放置一個皇后。
- 列約束和對角線約束的處理方式類似。對於列約束,我們利用一個陣列來記錄每一列是否有皇后,從而指示選中的格子是否合法。對於對角線約束,我們藉助兩個陣列來分別記錄該主、次對角線上是否存在皇后;難點在於找處在同一主(副)對角線上格子滿足的行列索引規律。
- 列約束和對角線約束的處理方式類似。對於列約束,我們利用一個陣列來記錄每一列是否有皇后,從而指示選中的格子是否合法。對於對角線約束,我們藉助兩個陣列來分別記錄該主、次對角線上是否存在皇后;難點在於找處在同一主(副)對角線上格子滿足的行列索引規律。
### 2. &nbsp; Q & A
@@ -544,6 +544,8 @@ comments: true
<div style="height: 549px; width: 100%;"><iframe class="pythontutor-iframe" src="https://pythontutor.com/iframe-embed.html#code=class%20Item%3A%0A%20%20%20%20%22%22%22%E7%89%A9%E5%93%81%22%22%22%0A%20%20%20%20def%20__init__%28self%2C%20w%3A%20int%2C%20v%3A%20int%29%3A%0A%20%20%20%20%20%20%20%20self.w%20%3D%20w%20%20%23%20%E7%89%A9%E5%93%81%E9%87%8D%E9%87%8F%0A%20%20%20%20%20%20%20%20self.v%20%3D%20v%20%20%23%20%E7%89%A9%E5%93%81%E5%83%B9%E5%80%BC%0A%0Adef%20fractional_knapsack%28wgt%3A%20list%5Bint%5D%2C%20val%3A%20list%5Bint%5D%2C%20cap%3A%20int%29%20-%3E%20int%3A%0A%20%20%20%20%22%22%22%E5%88%86%E6%95%B8%E8%83%8C%E5%8C%85%EF%BC%9A%E8%B2%AA%E5%A9%AA%22%22%22%0A%20%20%20%20%23%20%E5%BB%BA%E7%AB%8B%E7%89%A9%E5%93%81%E4%B8%B2%E5%88%97%EF%BC%8C%E5%8C%85%E5%90%AB%E5%85%A9%E5%80%8B%E5%B1%AC%E6%80%A7%EF%BC%9A%E9%87%8D%E9%87%8F%E3%80%81%E5%83%B9%E5%80%BC%0A%20%20%20%20items%20%3D%20%5BItem%28w%2C%20v%29%20for%20w%2C%20v%20in%20zip%28wgt%2C%20val%29%5D%0A%20%20%20%20%23%20%E6%8C%89%E7%85%A7%E5%96%AE%E4%BD%8D%E5%83%B9%E5%80%BC%20item.v%20/%20item.w%20%E5%BE%9E%E9%AB%98%E5%88%B0%E4%BD%8E%E9%80%B2%E8%A1%8C%E6%8E%92%E5%BA%8F%0A%20%20%20%20items.sort%28key%3Dlambda%20item%3A%20item.v%20/%20item.w%2C%20reverse%3DTrue%29%0A%20%20%20%20%23%20%E8%BF%B4%E5%9C%88%E8%B2%AA%E5%A9%AA%E9%81%B8%E6%93%87%0A%20%20%20%20res%20%3D%200%0A%20%20%20%20for%20item%20in%20items%3A%0A%20%20%20%20%20%20%20%20if%20item.w%20%3C%3D%20cap%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E8%8B%A5%E5%89%A9%E9%A4%98%E5%AE%B9%E9%87%8F%E5%85%85%E8%B6%B3%EF%BC%8C%E5%89%87%E5%B0%87%E7%95%B6%E5%89%8D%E7%89%A9%E5%93%81%E6%95%B4%E5%80%8B%E8%A3%9D%E9%80%B2%E8%83%8C%E5%8C%85%0A%20%20%20%20%20%20%20%20%20%20%20%20res%20%2B%3D%20item.v%0A%20%20%20%20%20%20%20%20%20%20%20%20cap%20-%3D%20item.w%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E8%8B%A5%E5%89%A9%E9%A4%98%E5%AE%B9%E9%87%8F%E4%B8%8D%E8%B6%B3%EF%BC%8C%E5%89%87%E5%B0%87%E7%95%B6%E5%89%8D%E7%89%A9%E5%93%81%E7%9A%84%E4%B8%80%E9%83%A8%E5%88%86%E8%A3%9D%E9%80%B2%E8%83%8C%E5%8C%85%0A%20%20%20%20%20%20%20%20%20%20%20%20res%20%2B%3D%20%28item.v%20/%20item.w%29%20%2A%20cap%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E5%B7%B2%E7%84%A1%E5%89%A9%E9%A4%98%E5%AE%B9%E9%87%8F%EF%BC%8C%E5%9B%A0%E6%AD%A4%E8%B7%B3%E5%87%BA%E8%BF%B4%E5%9C%88%0A%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20return%20res%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20wgt%20%3D%20%5B10%2C%2020%2C%2030%2C%2040%2C%2050%5D%0A%20%20%20%20val%20%3D%20%5B50%2C%20120%2C%20150%2C%20210%2C%20240%5D%0A%20%20%20%20cap%20%3D%2050%0A%20%20%20%20n%20%3D%20len%28wgt%29%0A%0A%20%20%20%20%23%20%E8%B2%AA%E5%A9%AA%E6%BC%94%E7%AE%97%E6%B3%95%0A%20%20%20%20res%20%3D%20fractional_knapsack%28wgt%2C%20val%2C%20cap%29%0A%20%20%20%20print%28f%22%E4%B8%8D%E8%B6%85%E9%81%8E%E8%83%8C%E5%8C%85%E5%AE%B9%E9%87%8F%E7%9A%84%E6%9C%80%E5%A4%A7%E7%89%A9%E5%93%81%E5%83%B9%E5%80%BC%E7%82%BA%20%7Bres%7D%22%29&codeDivHeight=472&codeDivWidth=350&cumulative=false&curInstr=8&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false"> </iframe></div>
<div style="margin-top: 5px;"><a href="https://pythontutor.com/iframe-embed.html#code=class%20Item%3A%0A%20%20%20%20%22%22%22%E7%89%A9%E5%93%81%22%22%22%0A%20%20%20%20def%20__init__%28self%2C%20w%3A%20int%2C%20v%3A%20int%29%3A%0A%20%20%20%20%20%20%20%20self.w%20%3D%20w%20%20%23%20%E7%89%A9%E5%93%81%E9%87%8D%E9%87%8F%0A%20%20%20%20%20%20%20%20self.v%20%3D%20v%20%20%23%20%E7%89%A9%E5%93%81%E5%83%B9%E5%80%BC%0A%0Adef%20fractional_knapsack%28wgt%3A%20list%5Bint%5D%2C%20val%3A%20list%5Bint%5D%2C%20cap%3A%20int%29%20-%3E%20int%3A%0A%20%20%20%20%22%22%22%E5%88%86%E6%95%B8%E8%83%8C%E5%8C%85%EF%BC%9A%E8%B2%AA%E5%A9%AA%22%22%22%0A%20%20%20%20%23%20%E5%BB%BA%E7%AB%8B%E7%89%A9%E5%93%81%E4%B8%B2%E5%88%97%EF%BC%8C%E5%8C%85%E5%90%AB%E5%85%A9%E5%80%8B%E5%B1%AC%E6%80%A7%EF%BC%9A%E9%87%8D%E9%87%8F%E3%80%81%E5%83%B9%E5%80%BC%0A%20%20%20%20items%20%3D%20%5BItem%28w%2C%20v%29%20for%20w%2C%20v%20in%20zip%28wgt%2C%20val%29%5D%0A%20%20%20%20%23%20%E6%8C%89%E7%85%A7%E5%96%AE%E4%BD%8D%E5%83%B9%E5%80%BC%20item.v%20/%20item.w%20%E5%BE%9E%E9%AB%98%E5%88%B0%E4%BD%8E%E9%80%B2%E8%A1%8C%E6%8E%92%E5%BA%8F%0A%20%20%20%20items.sort%28key%3Dlambda%20item%3A%20item.v%20/%20item.w%2C%20reverse%3DTrue%29%0A%20%20%20%20%23%20%E8%BF%B4%E5%9C%88%E8%B2%AA%E5%A9%AA%E9%81%B8%E6%93%87%0A%20%20%20%20res%20%3D%200%0A%20%20%20%20for%20item%20in%20items%3A%0A%20%20%20%20%20%20%20%20if%20item.w%20%3C%3D%20cap%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E8%8B%A5%E5%89%A9%E9%A4%98%E5%AE%B9%E9%87%8F%E5%85%85%E8%B6%B3%EF%BC%8C%E5%89%87%E5%B0%87%E7%95%B6%E5%89%8D%E7%89%A9%E5%93%81%E6%95%B4%E5%80%8B%E8%A3%9D%E9%80%B2%E8%83%8C%E5%8C%85%0A%20%20%20%20%20%20%20%20%20%20%20%20res%20%2B%3D%20item.v%0A%20%20%20%20%20%20%20%20%20%20%20%20cap%20-%3D%20item.w%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E8%8B%A5%E5%89%A9%E9%A4%98%E5%AE%B9%E9%87%8F%E4%B8%8D%E8%B6%B3%EF%BC%8C%E5%89%87%E5%B0%87%E7%95%B6%E5%89%8D%E7%89%A9%E5%93%81%E7%9A%84%E4%B8%80%E9%83%A8%E5%88%86%E8%A3%9D%E9%80%B2%E8%83%8C%E5%8C%85%0A%20%20%20%20%20%20%20%20%20%20%20%20res%20%2B%3D%20%28item.v%20/%20item.w%29%20%2A%20cap%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E5%B7%B2%E7%84%A1%E5%89%A9%E9%A4%98%E5%AE%B9%E9%87%8F%EF%BC%8C%E5%9B%A0%E6%AD%A4%E8%B7%B3%E5%87%BA%E8%BF%B4%E5%9C%88%0A%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20return%20res%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20wgt%20%3D%20%5B10%2C%2020%2C%2030%2C%2040%2C%2050%5D%0A%20%20%20%20val%20%3D%20%5B50%2C%20120%2C%20150%2C%20210%2C%20240%5D%0A%20%20%20%20cap%20%3D%2050%0A%20%20%20%20n%20%3D%20len%28wgt%29%0A%0A%20%20%20%20%23%20%E8%B2%AA%E5%A9%AA%E6%BC%94%E7%AE%97%E6%B3%95%0A%20%20%20%20res%20%3D%20fractional_knapsack%28wgt%2C%20val%2C%20cap%29%0A%20%20%20%20print%28f%22%E4%B8%8D%E8%B6%85%E9%81%8E%E8%83%8C%E5%8C%85%E5%AE%B9%E9%87%8F%E7%9A%84%E6%9C%80%E5%A4%A7%E7%89%A9%E5%93%81%E5%83%B9%E5%80%BC%E7%82%BA%20%7Bres%7D%22%29&codeDivHeight=800&codeDivWidth=600&cumulative=false&curInstr=8&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false" target="_blank" rel="noopener noreferrer">全螢幕觀看 ></a></div>
內建排序演算法的時間複雜度通常為 $O(\log n)$ ,空間複雜度通常為 $O(\log n)$ 或 $O(n)$ ,取決於程式語言的具體實現。
除排序之外,在最差情況下,需要走訪整個物品串列,**因此時間複雜度為 $O(n)$** ,其中 $n$ 為物品數量。
由於初始化了一個 `Item` 物件串列,**因此空間複雜度為 $O(n)$** 。
@@ -354,7 +354,7 @@ index = hash(key) % capacity
for (const c of key) {
hash ^= c.charCodeAt(0);
}
return hash & MODULUS;
return hash % MODULUS;
}
/* 旋轉雜湊 */
@@ -398,7 +398,7 @@ index = hash(key) % capacity
for (const c of key) {
hash ^= c.charCodeAt(0);
}
return hash & MODULUS;
return hash % MODULUS;
}
/* 旋轉雜湊 */
+11 -15
View File
@@ -1025,10 +1025,10 @@ comments: true
```rust title="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>>,
}
@@ -1046,7 +1046,7 @@ comments: true
/* 雜湊函式 */
fn hash_func(&self, key: i32) -> usize {
key as usize % self.capacity as usize
key as usize % self.capacity
}
/* 負載因子 */
@@ -1057,12 +1057,11 @@ comments: true
/* 刪除操作 */
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);
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);
}
@@ -1075,7 +1074,7 @@ comments: true
/* 擴容雜湊表 */
fn extend(&mut self) {
// 暫存原雜湊表
let buckets_tmp = std::mem::replace(&mut self.buckets, vec![]);
let buckets_tmp = std::mem::take(&mut self.buckets);
// 初始化擴容後的新雜湊表
self.capacity *= self.extend_ratio;
@@ -1109,30 +1108,27 @@ comments: true
}
let index = self.hash_func(key);
let bucket = &mut self.buckets[index];
// 走訪桶,若遇到指定 key ,則更新對應 val 並返回
for pair in bucket {
for pair in self.buckets[index].iter_mut() {
if pair.key == key {
pair.val = val;
return;
}
}
let bucket = &mut self.buckets[index];
// 若無該 key ,則將鍵值對新增至尾部
let pair = Pair { key, val };
bucket.push(pair);
self.buckets[index].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 {
for pair in self.buckets[index].iter() {
if pair.key == key {
return Some(&pair.val);
}
@@ -27,9 +27,7 @@ comments: true
"""計數排序"""
# 簡單實現,無法用於排序物件
# 1. 統計陣列最大元素 m
m = 0
for num in nums:
m = max(m, num)
m = max(nums)
# 2. 統計各數字的出現次數
# counter[num] 代表 num 的出現次數
counter = [0] * (m + 1)
+11 -7
View File
@@ -1679,7 +1679,7 @@ comments: true
}
}
self.que_size -= 1; // 更新佇列長度
Rc::try_unwrap(old_front).ok().unwrap().into_inner().val
old_front.borrow().val
})
}
// 佇列尾出列操作
@@ -1695,7 +1695,7 @@ comments: true
}
}
self.que_size -= 1; // 更新佇列長度
Rc::try_unwrap(old_rear).ok().unwrap().into_inner().val
old_rear.borrow().val
})
}
}
@@ -1722,12 +1722,16 @@ comments: true
/* 返回陣列用於列印 */
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;
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);
}
}
return Vec::new();
recur(head, &mut res);
res
}
}
```
+12 -6
View File
@@ -1070,7 +1070,7 @@ comments: true
}
}
self.que_size -= 1;
Rc::try_unwrap(old_front).ok().unwrap().into_inner().val
old_front.borrow().val
})
}
@@ -1081,12 +1081,18 @@ comments: true
/* 將鏈結串列轉化為 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;
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);
}
}
return Vec::new();
recur(head, &mut res);
res
}
}
```
@@ -964,16 +964,10 @@ comments: true
/* 出堆疊 */
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.stack_peek = old_head.borrow_mut().next.take();
self.stk_size -= 1;
Rc::try_unwrap(old_head).ok().unwrap().into_inner().val
old_head.borrow().val
})
}