这道题我感觉并不是很简单,因为递归的同时还要考虑SUM,但是又只能返回TreeNode *。
我用的递归,并假定NULL节点的SUM为0。用的全局变量来保存minValue和RecordNode。
这题要注意的地方:是当某个节点的左子节点或右子节点是NULL时,不能直接设minChildSum=min(sumLeft, sumRight); 因为NULL节点的SUM为0,所以肯定最小。测试特例:input = {1,#,2}。
代码如下:
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param root: the root of binary tree
* @return: the root of the minimum subtree
*/
TreeNode * findSubtree(TreeNode * root) {
if (!root) return NULL;
int sumLeft = sumSubTree(root->left);
int sumRight = sumSubTree(root->right);
int sumAll = sumLeft + sumRight + root->val;
int minChildSum;
if (!root->left)
minChildSum = sumRight;
else if (!root->right)
minChildSum = sumLeft;
else
minChildSum = min(sumLeft, sumRight);
if (sumAll < minValue) {
minValue = sumAll;
recordNode = root;
} else if (minChildSum < minValue) {
minValue = minChildSum;
recordNode = (sumLeft< sumRight)? root->left : root->right;
}
return recordNode;
}
private:
int sumSubTree(TreeNode * root) {
if (!root)
return 0;
else {
int sum = sumSubTree(root->left) + sumSubTree(root->right) + root->val;
if (sum < minValue) {
minValue = sum;
recordNode = root;
}
return sum;
}
}
int minValue=INT_MAX;
TreeNode *recordNode;
};
另外,我看了一下九章的方法是将返回类型包装成一个结构,包括TreeNode*, sum和minSum。这个技巧值得学习。
其参考代码如下,需要好好掌握。
// version 2: Pure divide conquer
class ResultType {
public TreeNode minSubtree;
public int sum, minSum;
public ResultType(TreeNode minSubtree, int minSum, int sum) {
this.minSubtree = minSubtree;
this.minSum = minSum;
this.sum = sum;
}
}
public class Solution {
/**
* @param root the root of binary tree
* @return the root of the minimum subtree
*/
public TreeNode findSubtree(TreeNode root) {
ResultType result = helper(root);
return result.minSubtree;
}
public ResultType helper(TreeNode node) {
if (node == null) {
return new ResultType(null, Integer.MAX_VALUE, 0);
}
ResultType leftResult = helper(node.left);
ResultType rightResult = helper(node.right);
ResultType result = new ResultType(
node,
leftResult.sum + rightResult.sum + node.val,
leftResult.sum + rightResult.sum + node.val
);
if (leftResult.minSum <= result.minSum) {
result.minSum = leftResult.minSum;
result.minSubtree = leftResult.minSubtree;
}
if (rightResult.minSum <= result.minSum) {
result.minSum = rightResult.minSum;
result.minSubtree = rightResult.minSubtree;
}
return result;
}
}
另外,发现还可以用超简洁的分治+遍历来解决这个问题(参考九章),代码如下:
class Solution {
public:
/**
* @param root: the root of binary tree
* @return: the root of the minimum subtree
*/
TreeNode * findSubtree(TreeNode * root) {
helper(root);
return recordRoot;
}
private:
int helper(TreeNode * root) {
if (!root)
return 0;
int sum = helper(root->left)+helper(root->right)+root->val;
if (sum < minSum) {
recordRoot = root;
minSum = sum;
}
return sum;
}
int minValue=INT_MAX;
TreeNode *recordNode;
};
三刷:
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param root: the root of binary tree
* @return: the root of the minimum subtree
*/
TreeNode* findSubtree(TreeNode *root) {
helper(root);
return minNode;
}
private:
int helper(TreeNode *root) {
if (!root) return 0;
if (!root->left && !root->right) {
if (root->val < minSum) {
minSum = root->val;
minNode = root;
}
return root->val;
}
int resLeft = helper(root->left);
int resRight = helper(root->right);
int resSelf = resLeft + resRight + root->val;
if (resLeft && resLeft < resRight && resLeft < resSelf && resLeft < minSum) {
minSum = resLeft;
minNode = root->left;
} else if (resRight && resRight < resLeft && resRight < resSelf && resRight < minSum) {
minSum = resRight;
minNode = root->right;
} else if (resSelf < minSum) {
minSum = resSelf;
minNode = root;
}
return resSelf;
}
int minSum = INT_MAX;
TreeNode *minNode = nullptr;
};