C++贪心深度优先搜索解析:2673. 使二叉树所有路径值相等的最小代价
题目2673要求找到使二叉树所有路径值相等所需的最小代价。这是一道结合贪心策略和深度优先搜索(DFS)技术的经典问题。下面是对该问题的一种常见解析思路:
问题解释
给定一个二叉树,每个节点都有一个值。需要调整这些节点的值,使得从根到每个叶子的路径的节点值之和都相等,同时要使调整的代价最小。调整一个节点值的代价为调整值的绝对差值。
解题思路
深度优先计算初始路径和:
- 我们首先可以使用深度优先搜索来计算每一条从根到叶子路径的初始和。通过递归遍历树,累积节点值直至叶子节点,这样可以获得所有路径的路径和。
确定最优路径和(目标路径和):
- 选择一个目标路径和,以此为标准来调整其他路径。一个合理的选择是将所有路径和的最大值作为目标路径和,这样能避免最坏情况下的过多调整。
调整路径:
- 再次使用深度优先搜索的方法,从根开始遍历每一条路径,同时计算当前路径需要调整的代价。
- 如果当前路径和小于目标路径和,在遍历的过程中累积所需的调整值,记录调整代价。
计算总代价:
- 对所有路径所需的调整代价进行累计,得到最终的最小总调整代价。
伪代码示例
int minCostToEqualPaths(TreeNode* root) {
vector<int> pathSums;
calculateInitialPathSums(root, 0, pathSums);
int targetSum = *max_element(pathSums.begin(), pathSums.end());
int totalCost = 0;
adjustPaths(root, 0, targetSum, totalCost);
return totalCost;
}
void calculateInitialPathSums(TreeNode* node, int currentSum, vector<int>& pathSums) {
if (!node) return;
currentSum += node->val;
if (!node->left && !node->right) {
pathSums.push_back(currentSum);
}
calculateInitialPathSums(node->left, currentSum, pathSums);
calculateInitialPathSums(node->right, currentSum, pathSums);
}
void adjustPaths(TreeNode* node, int currentSum, int targetSum, int& totalCost) {
if (!node) return;
currentSum += node->val;
if (!node->left && !node->right) {
totalCost += abs(targetSum - currentSum);
}
adjustPaths(node->left, currentSum, targetSum, totalCost);
adjustPaths(node->right, currentSum, targetSum, totalCost);
}
注意
- 这道题的核心是理解如何在保留“贪心”思想的前提下,通过“深度优先搜索”有效地遍历和调整路径。
- 确保目标路径和的合理选择以及在调整过程中对路径选择的正确处理是解决问题成功的关键。
- 边界条件(空树、单节点等)仍需小心处理。