mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 06:07:20 +08:00 
			
		
		
		
	Sync zh and zh-hant versions. (#1523)
This commit is contained in:
		@ -9,13 +9,6 @@
 | 
				
			|||||||
/* 快速排序類別 */
 | 
					/* 快速排序類別 */
 | 
				
			||||||
class QuickSort {
 | 
					class QuickSort {
 | 
				
			||||||
  private:
 | 
					  private:
 | 
				
			||||||
    /* 元素交換 */
 | 
					 | 
				
			||||||
    static void swap(vector<int> &nums, int i, int j) {
 | 
					 | 
				
			||||||
        int tmp = nums[i];
 | 
					 | 
				
			||||||
        nums[i] = nums[j];
 | 
					 | 
				
			||||||
        nums[j] = tmp;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* 哨兵劃分 */
 | 
					    /* 哨兵劃分 */
 | 
				
			||||||
    static int partition(vector<int> &nums, int left, int right) {
 | 
					    static int partition(vector<int> &nums, int left, int right) {
 | 
				
			||||||
        // 以 nums[left] 為基準數
 | 
					        // 以 nums[left] 為基準數
 | 
				
			||||||
@ -25,9 +18,9 @@ class QuickSort {
 | 
				
			|||||||
                j--;                // 從右向左找首個小於基準數的元素
 | 
					                j--;                // 從右向左找首個小於基準數的元素
 | 
				
			||||||
            while (i < j && nums[i] <= nums[left])
 | 
					            while (i < j && nums[i] <= nums[left])
 | 
				
			||||||
                i++;                // 從左向右找首個大於基準數的元素
 | 
					                i++;                // 從左向右找首個大於基準數的元素
 | 
				
			||||||
            swap(nums, i, j); // 交換這兩個元素
 | 
					            swap(nums[i], nums[j]); // 交換這兩個元素
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        swap(nums, i, left); // 將基準數交換至兩子陣列的分界線
 | 
					        swap(nums[i], nums[left]);  // 將基準數交換至兩子陣列的分界線
 | 
				
			||||||
        return i;                   // 返回基準數的索引
 | 
					        return i;                   // 返回基準數的索引
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -48,13 +41,6 @@ class QuickSort {
 | 
				
			|||||||
/* 快速排序類別(中位基準數最佳化) */
 | 
					/* 快速排序類別(中位基準數最佳化) */
 | 
				
			||||||
class QuickSortMedian {
 | 
					class QuickSortMedian {
 | 
				
			||||||
  private:
 | 
					  private:
 | 
				
			||||||
    /* 元素交換 */
 | 
					 | 
				
			||||||
    static void swap(vector<int> &nums, int i, int j) {
 | 
					 | 
				
			||||||
        int tmp = nums[i];
 | 
					 | 
				
			||||||
        nums[i] = nums[j];
 | 
					 | 
				
			||||||
        nums[j] = tmp;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* 選取三個候選元素的中位數 */
 | 
					    /* 選取三個候選元素的中位數 */
 | 
				
			||||||
    static int medianThree(vector<int> &nums, int left, int mid, int right) {
 | 
					    static int medianThree(vector<int> &nums, int left, int mid, int right) {
 | 
				
			||||||
        int l = nums[left], m = nums[mid], r = nums[right];
 | 
					        int l = nums[left], m = nums[mid], r = nums[right];
 | 
				
			||||||
@ -70,7 +56,7 @@ class QuickSortMedian {
 | 
				
			|||||||
        // 選取三個候選元素的中位數
 | 
					        // 選取三個候選元素的中位數
 | 
				
			||||||
        int med = medianThree(nums, left, (left + right) / 2, right);
 | 
					        int med = medianThree(nums, left, (left + right) / 2, right);
 | 
				
			||||||
        // 將中位數交換至陣列最左端
 | 
					        // 將中位數交換至陣列最左端
 | 
				
			||||||
        swap(nums, left, med);
 | 
					        swap(nums[left], nums[med]);
 | 
				
			||||||
        // 以 nums[left] 為基準數
 | 
					        // 以 nums[left] 為基準數
 | 
				
			||||||
        int i = left, j = right;
 | 
					        int i = left, j = right;
 | 
				
			||||||
        while (i < j) {
 | 
					        while (i < j) {
 | 
				
			||||||
@ -78,9 +64,9 @@ class QuickSortMedian {
 | 
				
			|||||||
                j--;                // 從右向左找首個小於基準數的元素
 | 
					                j--;                // 從右向左找首個小於基準數的元素
 | 
				
			||||||
            while (i < j && nums[i] <= nums[left])
 | 
					            while (i < j && nums[i] <= nums[left])
 | 
				
			||||||
                i++;                // 從左向右找首個大於基準數的元素
 | 
					                i++;                // 從左向右找首個大於基準數的元素
 | 
				
			||||||
            swap(nums, i, j); // 交換這兩個元素
 | 
					            swap(nums[i], nums[j]); // 交換這兩個元素
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        swap(nums, i, left); // 將基準數交換至兩子陣列的分界線
 | 
					        swap(nums[i], nums[left]);  // 將基準數交換至兩子陣列的分界線
 | 
				
			||||||
        return i;                   // 返回基準數的索引
 | 
					        return i;                   // 返回基準數的索引
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -101,13 +87,6 @@ class QuickSortMedian {
 | 
				
			|||||||
/* 快速排序類別(尾遞迴最佳化) */
 | 
					/* 快速排序類別(尾遞迴最佳化) */
 | 
				
			||||||
class QuickSortTailCall {
 | 
					class QuickSortTailCall {
 | 
				
			||||||
  private:
 | 
					  private:
 | 
				
			||||||
    /* 元素交換 */
 | 
					 | 
				
			||||||
    static void swap(vector<int> &nums, int i, int j) {
 | 
					 | 
				
			||||||
        int tmp = nums[i];
 | 
					 | 
				
			||||||
        nums[i] = nums[j];
 | 
					 | 
				
			||||||
        nums[j] = tmp;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* 哨兵劃分 */
 | 
					    /* 哨兵劃分 */
 | 
				
			||||||
    static int partition(vector<int> &nums, int left, int right) {
 | 
					    static int partition(vector<int> &nums, int left, int right) {
 | 
				
			||||||
        // 以 nums[left] 為基準數
 | 
					        // 以 nums[left] 為基準數
 | 
				
			||||||
@ -117,9 +96,9 @@ class QuickSortTailCall {
 | 
				
			|||||||
                j--;                // 從右向左找首個小於基準數的元素
 | 
					                j--;                // 從右向左找首個小於基準數的元素
 | 
				
			||||||
            while (i < j && nums[i] <= nums[left])
 | 
					            while (i < j && nums[i] <= nums[left])
 | 
				
			||||||
                i++;                // 從左向右找首個大於基準數的元素
 | 
					                i++;                // 從左向右找首個大於基準數的元素
 | 
				
			||||||
            swap(nums, i, j); // 交換這兩個元素
 | 
					            swap(nums[i], nums[j]); // 交換這兩個元素
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        swap(nums, i, left); // 將基準數交換至兩子陣列的分界線
 | 
					        swap(nums[i], nums[left]);  // 將基準數交換至兩子陣列的分界線
 | 
				
			||||||
        return i;                   // 返回基準數的索引
 | 
					        return i;                   // 返回基準數的索引
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -70,7 +70,7 @@ class MyList {
 | 
				
			|||||||
    remove(index) {
 | 
					    remove(index) {
 | 
				
			||||||
        if (index < 0 || index >= this.#size) throw new Error('索引越界');
 | 
					        if (index < 0 || index >= this.#size) throw new Error('索引越界');
 | 
				
			||||||
        let num = this.#arr[index];
 | 
					        let num = this.#arr[index];
 | 
				
			||||||
        // 將將索引 index 之後的元素都向前移動一位
 | 
					        // 將索引 index 之後的元素都向前移動一位
 | 
				
			||||||
        for (let j = index; j < this.#size - 1; j++) {
 | 
					        for (let j = index; j < this.#size - 1; j++) {
 | 
				
			||||||
            this.#arr[j] = this.#arr[j + 1];
 | 
					            this.#arr[j] = this.#arr[j + 1];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -16,11 +16,7 @@ fn backtrack(
 | 
				
			|||||||
) {
 | 
					) {
 | 
				
			||||||
    // 當放置完所有行時,記錄解
 | 
					    // 當放置完所有行時,記錄解
 | 
				
			||||||
    if row == n {
 | 
					    if row == n {
 | 
				
			||||||
        let mut copy_state: Vec<Vec<String>> = Vec::new();
 | 
					        res.push(state.clone());
 | 
				
			||||||
        for s_row in state.clone() {
 | 
					 | 
				
			||||||
            copy_state.push(s_row);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        res.push(copy_state);
 | 
					 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // 走訪所有列
 | 
					    // 走訪所有列
 | 
				
			||||||
@ -31,12 +27,12 @@ fn backtrack(
 | 
				
			|||||||
        // 剪枝:不允許該格子所在列、主對角線、次對角線上存在皇后
 | 
					        // 剪枝:不允許該格子所在列、主對角線、次對角線上存在皇后
 | 
				
			||||||
        if !cols[col] && !diags1[diag1] && !diags2[diag2] {
 | 
					        if !cols[col] && !diags1[diag1] && !diags2[diag2] {
 | 
				
			||||||
            // 嘗試:將皇后放置在該格子
 | 
					            // 嘗試:將皇后放置在該格子
 | 
				
			||||||
            state.get_mut(row).unwrap()[col] = "Q".into();
 | 
					            state[row][col] = "Q".into();
 | 
				
			||||||
            (cols[col], diags1[diag1], diags2[diag2]) = (true, true, true);
 | 
					            (cols[col], diags1[diag1], diags2[diag2]) = (true, true, true);
 | 
				
			||||||
            // 放置下一行
 | 
					            // 放置下一行
 | 
				
			||||||
            backtrack(row + 1, n, state, res, cols, diags1, diags2);
 | 
					            backtrack(row + 1, n, state, res, cols, diags1, diags2);
 | 
				
			||||||
            // 回退:將該格子恢復為空位
 | 
					            // 回退:將該格子恢復為空位
 | 
				
			||||||
            state.get_mut(row).unwrap()[col] = "#".into();
 | 
					            state[row][col] = "#".into();
 | 
				
			||||||
            (cols[col], diags1[diag1], diags2[diag2]) = (false, false, false);
 | 
					            (cols[col], diags1[diag1], diags2[diag2]) = (false, false, false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -45,14 +41,7 @@ fn backtrack(
 | 
				
			|||||||
/* 求解 n 皇后 */
 | 
					/* 求解 n 皇后 */
 | 
				
			||||||
fn n_queens(n: usize) -> Vec<Vec<Vec<String>>> {
 | 
					fn n_queens(n: usize) -> Vec<Vec<Vec<String>>> {
 | 
				
			||||||
    // 初始化 n*n 大小的棋盤,其中 'Q' 代表皇后,'#' 代表空位
 | 
					    // 初始化 n*n 大小的棋盤,其中 'Q' 代表皇后,'#' 代表空位
 | 
				
			||||||
    let mut state: Vec<Vec<String>> = Vec::new();
 | 
					    let mut state: Vec<Vec<String>> = vec![vec!["#".to_string(); n]; n];
 | 
				
			||||||
    for _ in 0..n {
 | 
					 | 
				
			||||||
        let mut row: Vec<String> = Vec::new();
 | 
					 | 
				
			||||||
        for _ in 0..n {
 | 
					 | 
				
			||||||
            row.push("#".into());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        state.push(row);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    let mut cols = vec![false; n]; // 記錄列是否有皇后
 | 
					    let mut cols = vec![false; n]; // 記錄列是否有皇后
 | 
				
			||||||
    let mut diags1 = vec![false; 2 * n - 1]; // 記錄主對角線上是否有皇后
 | 
					    let mut diags1 = vec![false; 2 * n - 1]; // 記錄主對角線上是否有皇后
 | 
				
			||||||
    let mut diags2 = vec![false; 2 * n - 1]; // 記錄次對角線上是否有皇后
 | 
					    let mut diags2 = vec![false; 2 * n - 1]; // 記錄次對角線上是否有皇后
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* 回溯演算法:子集和 I */
 | 
					/* 回溯演算法:子集和 I */
 | 
				
			||||||
fn backtrack(
 | 
					fn backtrack(
 | 
				
			||||||
    mut state: Vec<i32>,
 | 
					    state: &mut Vec<i32>,
 | 
				
			||||||
    target: i32,
 | 
					    target: i32,
 | 
				
			||||||
    choices: &[i32],
 | 
					    choices: &[i32],
 | 
				
			||||||
    start: usize,
 | 
					    start: usize,
 | 
				
			||||||
@ -14,7 +14,7 @@ fn backtrack(
 | 
				
			|||||||
) {
 | 
					) {
 | 
				
			||||||
    // 子集和等於 target 時,記錄解
 | 
					    // 子集和等於 target 時,記錄解
 | 
				
			||||||
    if target == 0 {
 | 
					    if target == 0 {
 | 
				
			||||||
        res.push(state);
 | 
					        res.push(state.clone());
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // 走訪所有選擇
 | 
					    // 走訪所有選擇
 | 
				
			||||||
@ -28,7 +28,7 @@ fn backtrack(
 | 
				
			|||||||
        // 嘗試:做出選擇,更新 target, start
 | 
					        // 嘗試:做出選擇,更新 target, start
 | 
				
			||||||
        state.push(choices[i]);
 | 
					        state.push(choices[i]);
 | 
				
			||||||
        // 進行下一輪選擇
 | 
					        // 進行下一輪選擇
 | 
				
			||||||
        backtrack(state.clone(), target - choices[i], choices, i, res);
 | 
					        backtrack(state, target - choices[i], choices, i, res);
 | 
				
			||||||
        // 回退:撤銷選擇,恢復到之前的狀態
 | 
					        // 回退:撤銷選擇,恢復到之前的狀態
 | 
				
			||||||
        state.pop();
 | 
					        state.pop();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -36,11 +36,11 @@ fn backtrack(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* 求解子集和 I */
 | 
					/* 求解子集和 I */
 | 
				
			||||||
fn subset_sum_i(nums: &mut [i32], target: i32) -> Vec<Vec<i32>> {
 | 
					fn subset_sum_i(nums: &mut [i32], target: i32) -> Vec<Vec<i32>> {
 | 
				
			||||||
    let state = Vec::new(); // 狀態(子集)
 | 
					    let mut state = Vec::new(); // 狀態(子集)
 | 
				
			||||||
    nums.sort(); // 對 nums 進行排序
 | 
					    nums.sort(); // 對 nums 進行排序
 | 
				
			||||||
    let start = 0; // 走訪起始點
 | 
					    let start = 0; // 走訪起始點
 | 
				
			||||||
    let mut res = Vec::new(); // 結果串列(子集串列)
 | 
					    let mut res = Vec::new(); // 結果串列(子集串列)
 | 
				
			||||||
    backtrack(state, target, nums, start, &mut res);
 | 
					    backtrack(&mut state, target, nums, start, &mut res);
 | 
				
			||||||
    res
 | 
					    res
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* 回溯演算法:子集和 I */
 | 
					/* 回溯演算法:子集和 I */
 | 
				
			||||||
fn backtrack(
 | 
					fn backtrack(
 | 
				
			||||||
    mut state: Vec<i32>,
 | 
					    state: &mut Vec<i32>,
 | 
				
			||||||
    target: i32,
 | 
					    target: i32,
 | 
				
			||||||
    total: i32,
 | 
					    total: i32,
 | 
				
			||||||
    choices: &[i32],
 | 
					    choices: &[i32],
 | 
				
			||||||
@ -14,7 +14,7 @@ fn backtrack(
 | 
				
			|||||||
) {
 | 
					) {
 | 
				
			||||||
    // 子集和等於 target 時,記錄解
 | 
					    // 子集和等於 target 時,記錄解
 | 
				
			||||||
    if total == target {
 | 
					    if total == target {
 | 
				
			||||||
        res.push(state);
 | 
					        res.push(state.clone());
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // 走訪所有選擇
 | 
					    // 走訪所有選擇
 | 
				
			||||||
@ -26,7 +26,7 @@ fn backtrack(
 | 
				
			|||||||
        // 嘗試:做出選擇,更新元素和 total
 | 
					        // 嘗試:做出選擇,更新元素和 total
 | 
				
			||||||
        state.push(choices[i]);
 | 
					        state.push(choices[i]);
 | 
				
			||||||
        // 進行下一輪選擇
 | 
					        // 進行下一輪選擇
 | 
				
			||||||
        backtrack(state.clone(), target, total + choices[i], choices, res);
 | 
					        backtrack(state, target, total + choices[i], choices, res);
 | 
				
			||||||
        // 回退:撤銷選擇,恢復到之前的狀態
 | 
					        // 回退:撤銷選擇,恢復到之前的狀態
 | 
				
			||||||
        state.pop();
 | 
					        state.pop();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -34,10 +34,10 @@ fn backtrack(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* 求解子集和 I(包含重複子集) */
 | 
					/* 求解子集和 I(包含重複子集) */
 | 
				
			||||||
fn subset_sum_i_naive(nums: &[i32], target: i32) -> Vec<Vec<i32>> {
 | 
					fn subset_sum_i_naive(nums: &[i32], target: i32) -> Vec<Vec<i32>> {
 | 
				
			||||||
    let state = Vec::new(); // 狀態(子集)
 | 
					    let mut state = Vec::new(); // 狀態(子集)
 | 
				
			||||||
    let total = 0; // 子集和
 | 
					    let total = 0; // 子集和
 | 
				
			||||||
    let mut res = Vec::new(); // 結果串列(子集串列)
 | 
					    let mut res = Vec::new(); // 結果串列(子集串列)
 | 
				
			||||||
    backtrack(state, target, total, nums, &mut res);
 | 
					    backtrack(&mut state, target, total, nums, &mut res);
 | 
				
			||||||
    res
 | 
					    res
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* 回溯演算法:子集和 II */
 | 
					/* 回溯演算法:子集和 II */
 | 
				
			||||||
fn backtrack(
 | 
					fn backtrack(
 | 
				
			||||||
    mut state: Vec<i32>,
 | 
					    state: &mut Vec<i32>,
 | 
				
			||||||
    target: i32,
 | 
					    target: i32,
 | 
				
			||||||
    choices: &[i32],
 | 
					    choices: &[i32],
 | 
				
			||||||
    start: usize,
 | 
					    start: usize,
 | 
				
			||||||
@ -14,7 +14,7 @@ fn backtrack(
 | 
				
			|||||||
) {
 | 
					) {
 | 
				
			||||||
    // 子集和等於 target 時,記錄解
 | 
					    // 子集和等於 target 時,記錄解
 | 
				
			||||||
    if target == 0 {
 | 
					    if target == 0 {
 | 
				
			||||||
        res.push(state);
 | 
					        res.push(state.clone());
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // 走訪所有選擇
 | 
					    // 走訪所有選擇
 | 
				
			||||||
@ -33,7 +33,7 @@ fn backtrack(
 | 
				
			|||||||
        // 嘗試:做出選擇,更新 target, start
 | 
					        // 嘗試:做出選擇,更新 target, start
 | 
				
			||||||
        state.push(choices[i]);
 | 
					        state.push(choices[i]);
 | 
				
			||||||
        // 進行下一輪選擇
 | 
					        // 進行下一輪選擇
 | 
				
			||||||
        backtrack(state.clone(), target - choices[i], choices, i + 1, res);
 | 
					        backtrack(state, target - choices[i], choices, i + 1, res);
 | 
				
			||||||
        // 回退:撤銷選擇,恢復到之前的狀態
 | 
					        // 回退:撤銷選擇,恢復到之前的狀態
 | 
				
			||||||
        state.pop();
 | 
					        state.pop();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -41,11 +41,11 @@ fn backtrack(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* 求解子集和 II */
 | 
					/* 求解子集和 II */
 | 
				
			||||||
fn subset_sum_ii(nums: &mut [i32], target: i32) -> Vec<Vec<i32>> {
 | 
					fn subset_sum_ii(nums: &mut [i32], target: i32) -> Vec<Vec<i32>> {
 | 
				
			||||||
    let state = Vec::new(); // 狀態(子集)
 | 
					    let mut state = Vec::new(); // 狀態(子集)
 | 
				
			||||||
    nums.sort(); // 對 nums 進行排序
 | 
					    nums.sort(); // 對 nums 進行排序
 | 
				
			||||||
    let start = 0; // 走訪起始點
 | 
					    let start = 0; // 走訪起始點
 | 
				
			||||||
    let mut res = Vec::new(); // 結果串列(子集串列)
 | 
					    let mut res = Vec::new(); // 結果串列(子集串列)
 | 
				
			||||||
    backtrack(state, target, nums, start, &mut res);
 | 
					    backtrack(&mut state, target, nums, start, &mut res);
 | 
				
			||||||
    res
 | 
					    res
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -29,7 +29,7 @@ impl<T> ListNode<T> {
 | 
				
			|||||||
        for item in array.iter().rev() {
 | 
					        for item in array.iter().rev() {
 | 
				
			||||||
            let node = Rc::new(RefCell::new(ListNode {
 | 
					            let node = Rc::new(RefCell::new(ListNode {
 | 
				
			||||||
                val: *item,
 | 
					                val: *item,
 | 
				
			||||||
                next: head.clone(),
 | 
					                next: head.take(),
 | 
				
			||||||
            }));
 | 
					            }));
 | 
				
			||||||
            head = Some(node);
 | 
					            head = Some(node);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -44,14 +44,14 @@ impl<T> ListNode<T> {
 | 
				
			|||||||
        T: std::hash::Hash + Eq + Copy + Clone,
 | 
					        T: std::hash::Hash + Eq + Copy + Clone,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        let mut hashmap = HashMap::new();
 | 
					        let mut hashmap = HashMap::new();
 | 
				
			||||||
        if let Some(node) = linked_list {
 | 
					        let mut node = linked_list;
 | 
				
			||||||
            let mut current = Some(node.clone());
 | 
					
 | 
				
			||||||
            while let Some(cur) = current {
 | 
					        while let Some(cur) = node {
 | 
				
			||||||
            let borrow = cur.borrow();
 | 
					            let borrow = cur.borrow();
 | 
				
			||||||
            hashmap.insert(borrow.val.clone(), cur.clone());
 | 
					            hashmap.insert(borrow.val.clone(), cur.clone());
 | 
				
			||||||
                current = borrow.next.clone();
 | 
					            node = borrow.next.clone();
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        hashmap
 | 
					        hashmap
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -72,23 +72,21 @@ pub fn vec_to_tree(arr: Vec<Option<i32>>) -> Option<Rc<RefCell<TreeNode>>> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 將二元樹序列化為串列:遞迴 */
 | 
					/* 將二元樹序列化為串列:遞迴 */
 | 
				
			||||||
fn tree_to_vec_dfs(root: Option<Rc<RefCell<TreeNode>>>, i: usize, res: &mut Vec<Option<i32>>) {
 | 
					fn tree_to_vec_dfs(root: Option<&Rc<RefCell<TreeNode>>>, i: usize, res: &mut Vec<Option<i32>>) {
 | 
				
			||||||
    if root.is_none() {
 | 
					    if let Some(root) = root {
 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    let root = root.unwrap();
 | 
					 | 
				
			||||||
        // i + 1 is the minimum valid size to access index i
 | 
					        // i + 1 is the minimum valid size to access index i
 | 
				
			||||||
        while res.len() < i + 1 {
 | 
					        while res.len() < i + 1 {
 | 
				
			||||||
            res.push(None);
 | 
					            res.push(None);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        res[i] = Some(root.borrow().val);
 | 
					        res[i] = Some(root.borrow().val);
 | 
				
			||||||
    tree_to_vec_dfs(root.borrow().left.clone(), 2 * i + 1, res);
 | 
					        tree_to_vec_dfs(root.borrow().left.as_ref(), 2 * i + 1, res);
 | 
				
			||||||
    tree_to_vec_dfs(root.borrow().right.clone(), 2 * i + 2, res);
 | 
					        tree_to_vec_dfs(root.borrow().right.as_ref(), 2 * i + 2, res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 將二元樹序列化為串列 */
 | 
					/* 將二元樹序列化為串列 */
 | 
				
			||||||
pub fn tree_to_vec(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<Option<i32>> {
 | 
					pub fn tree_to_vec(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<Option<i32>> {
 | 
				
			||||||
    let mut res = vec![];
 | 
					    let mut res = vec![];
 | 
				
			||||||
    tree_to_vec_dfs(root, 0, &mut res);
 | 
					    tree_to_vec_dfs(root.as_ref(), 0, &mut res);
 | 
				
			||||||
    res
 | 
					    res
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -635,8 +635,8 @@
 | 
				
			|||||||
    /* 雙向鏈結串列節點類別 */
 | 
					    /* 雙向鏈結串列節點類別 */
 | 
				
			||||||
    class ListNode {
 | 
					    class ListNode {
 | 
				
			||||||
        int val;        // 節點值
 | 
					        int val;        // 節點值
 | 
				
			||||||
        ListNode next;  // 指向後繼節點的引用
 | 
					        ListNode? next;  // 指向後繼節點的引用
 | 
				
			||||||
        ListNode prev;  // 指向前驅節點的引用
 | 
					        ListNode? prev;  // 指向前驅節點的引用
 | 
				
			||||||
        ListNode(this.val, [this.next, this.prev]);  // 建構子
 | 
					        ListNode(this.val, [this.next, this.prev]);  // 建構子
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    ```
 | 
					    ```
 | 
				
			||||||
 | 
				
			|||||||
@ -651,7 +651,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
### 完全二元樹
 | 
					### 完全二元樹
 | 
				
			||||||
 | 
					
 | 
				
			||||||
如下圖所示,<u>完全二元樹(complete binary tree)</u>只有最底層的節點未被填滿,且最底層節點儘量靠左填充。
 | 
					如下圖所示,<u>完全二元樹(complete binary tree)</u>只有最底層的節點未被填滿,且最底層節點儘量靠左填充。請注意,完美二元樹也是一棵完全二元樹。
 | 
				
			||||||
 | 
					
 | 
				
			||||||

 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
# Hello 演算法
 | 
					# Hello 演算法
 | 
				
			||||||
 | 
					
 | 
				
			||||||
動畫圖解、一鍵執行的資料結構與演算法教程
 | 
					動畫圖解、一鍵執行的資料結構與演算法教程。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[開始閱讀](chapter_hello_algo/)
 | 
					[開始閱讀](chapter_hello_algo/)
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user