我正在尝试解决一个简单的二叉树问题,将现有的二叉树转换为求和树。 递归解决方案是:
class Solution{
public void toSumTree(Node root){
solve(root);
}
private int solve(Node node){
if(node == null){
return 0;
}
int leftSubtreeValue = solve(node.left);
int rightSubtreeValue = solve(node.right);
int currentNodeValue = node.data;
node.data = leftSubtreeValue + rightSubtreeValue;
return currentNodeValue + leftSubtreeValue + rightSubtreeValue;
}
}
这给我们时间和空间复杂度分别为 O(N) 和 O(H)。
现在,由于上述递归方法类似于后序遍历,我认为我们可以使用某种版本的迭代后序遍历,如下所示:
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> postOrderTrvNodes = new LinkedList<>();
if(root == null){
return postOrderTrvNodes;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode current = root;
TreeNode lastVisited = null;
while (!stack.isEmpty() || current != null) {
if (current != null) {
stack.push(current);
current = current.left;
} else {
TreeNode peekNode = stack.peek();
if (peekNode.right != null && peekNode.right != lastVisited) {
current = peekNode.right;
} else {
TreeNode poppedNode = stack.pop();
postOrderTrvNodes.add(poppedNode.val);
lastVisited = poppedNode;
}
}
}
return postOrderTrvNodes;
}
}
我无法想出的是如何在每个节点存储所需的子树之和,以使空间复杂度保持为 O(H)。如果我们使用 HashMap 来存储 HashMap 中当前节点的子树之和
我想要的是一些可以普遍遵循的协议来模仿 Java 使用内部堆栈所做的事情。
您可以使用迭代方法来模拟递归解决方案的行为,而无需使用 HashMap 等附加数据结构。 这是修改后的迭代方法:
class Solution {
public void toSumTree(TreeNode root) {
if (root == null) {
return;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode current = root;
TreeNode lastVisited = null;
while (!stack.isEmpty() || current != null) {
if (current != null) {
stack.push(current);
current = current.left;
} else {
TreeNode peekNode = stack.peek();
if (peekNode.right != null && peekNode.right != lastVisited) {
current = peekNode.right;
} else {
TreeNode poppedNode = stack.pop();
// Save the original value of the current node
int originalValue = poppedNode.val;
// Update the current node value with the sum of left and right subtrees
poppedNode.val = getSubtreeSum(poppedNode.left) + getSubtreeSum(poppedNode.right);
// Update the lastVisited to the current node
lastVisited = poppedNode;
// Update the parent node with the new value
if (!stack.isEmpty()) {
TreeNode parentNode = stack.peek();
if (parentNode.left == poppedNode) {
parentNode.left.val = originalValue;
} else {
parentNode.right.val = originalValue;
}
}
}
}
}
}
private int getSubtreeSum(TreeNode node) {
return (node != null) ? node.val : 0;
}
}
在此代码中:
lastVisited 变量来跟踪我们最后访问的节点 处理。这让我们能够区分左和右 使用新值更新父节点时的子树。
originalValue) 计算左子树和右子树的总和。
祝你好运:)