
題目解析: 在二元搜尋樹中尋找特定數值的節點,將其刪除後回傳更新後的根節點,並確保留下的樹結構依然符合二元搜尋樹的性質。
解題思路: 利用遞迴尋找目標。如果目標值小於當前節點就往左找,大於就往右找。若剛好命中目標,分三種情況處理:如果左子樹為空,直接接上右子樹;如果右子樹為空,直接接上左子樹;如果兩邊都有,則設指標 q 走進右子樹並一路向左到底找出最小值,用它取代當前節點的值,最後遞迴呼叫刪除函數把那個最小值節點拔除。
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if (!root) return nullptr;
if (key < root->val) {
root->left = deleteNode(root->left, key);
} else if (key > root->val) {
root->right = deleteNode(root->right, key);
} else {
if (!root->left) return root->right;
if (!root->right) return root->left;
TreeNode* q = root->right;
while (q->left) q = q->left;
root->val = q->val;
root->right = deleteNode(root->right, q->val);
}
return root;
}
};

題目解析: 給定一棵二元樹與目標總和,計算所有「由上往下」相加等於目標值的路徑數量,路徑不需要從根節點開始,也不一定要在葉節點結束。
解題思路: 結合 DFS 遞迴與前綴和的概念來最佳化。設變數 ans 記錄路徑總數,雜湊表 v 記錄過往路徑累積總和出現的次數(初始先放入 v[0] = 1)。遞迴時將當前節點值加入累積總和,若 總和 - 目標值 已經存在於 v 中,代表中間有一段路徑剛好等於目標值,將其出現次數加給 ans。接著把當前總和次數加一,繼續往左右子樹尋找,找完後將次數減一進行回溯。
class Solution {
public:
int ans = 0;
unordered_map<long long, int> v;
int pathSum(TreeNode* root, int targetSum) {
v[0] = 1;
solve(root, 0, targetSum);
return ans;
}
void solve(TreeNode* now, long long sum, int targetSum) {
if (!now) return;
sum += now->val;
if (v.count(sum - targetSum)) {
ans += v[sum - targetSum];
}
v[sum]++;
solve(now->left, sum, targetSum);
solve(now->right, sum, targetSum);
v[sum]--;
}
};