LeetCode 437.:Path Sum III
第一个想法就是遍历二叉树,找出每个节点的可能性。这个思路时间复杂度为O(n^2)。
private int num;
public int pathSum(TreeNode root, int sum) {
if(root == null) return num;
recur(root, sum, 0);
pathSum(root.left, sum);
pathSum(root.right, sum);
return num;
}
private void recur(TreeNode root, int sum, int add) {
if(root == null) {
return;
}
add += root.val;
if (add == sum) num++;
recur(root.left, sum, add);
recur(root.right, sum, add);
}
改进下代码
public int pathSum2(TreeNode root, int sum) {
if(root == null) return 0;
return recur(root, sum) + pathSum2(root.left, sum) + pathSum2(root.right, sum);
}
private int recur(TreeNode node, int sum) {
if (node == null) return 0;
return (node.val == sum ? 1: 0) + recur(node.left, sum-node.val) +
recur(node.right, sum - node.val);
}
考虑用额外空间来缩短时间复杂度,采用map,其key为从根节点到该节点这条路径上所有节点值的和,value记录该值在整个树中一共有几条这样的路径(都是从根节点开始)。则递归过程中符合要救的路径的个数:
count=map.get(sum-target) ? 0 : 1;
public int pathSum3(TreeNode root, int target) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
map.put(0, 1); //sum-target == 0,则应返回1,表示有一条合格路径
return recur(root, 0, target, map);
}
private int recur(TreeNode node, int sum, int target, Map<Integer, Integer> map){
if(node == null) return 0;
sum += node.val;
// 表示有count条到node的路径(从任意二叉树节点开始)符合要求
int count = map.getOrDefault(sum-target,0);
map.put(sum, map.getOrDefault(sum, 0)+1);
count += recur(node.left, sum, target, map) + recur(node.right, sum, target, map);
// 回溯过程要清除该节点的记录
map.put(sum, map.get(sum)-1);
return count;
}
538. Convert BST to Greater Tree
// 解法一:利用中序遍历
private int sum;
public TreeNode convertBST(TreeNode root) {
if(root == null) return null;
convertBST(root.right);
sum += root.val;
root.val = sum;
convertBST(root.left);
return root;
}
解法二
// 解法二:利用栈
public TreeNode convertBST2(TreeNode root) {
int sum = 0;
ArrayDeque<TreeNode> stack = new ArrayDeque<>();
TreeNode res = root;
while (!stack.isEmpty() || root != null) {
while(root != null) {
stack.addLast(root);
root = root.right;
}
root = stack.pollLast();
sum += root.val;
root.val = sum;
root = root.left;
}
return res;
}
解法三:
// 解法三:morris 算法,前面两种解法的时间与空间复杂度均为O(n)
// morris算法的空间复杂度为O( 1 )
public TreeNode convertBST3(TreeNode root) {
int sum = 0;
TreeNode node = root;
while (node != null) {
if (node.right == null) {
sum += node.val;
node.val = sum;
node = node.left;
}
else {
TreeNode succ = getSuccessor(node);
if (succ.left == null) {
succ.left = node;
node = node.right;
}
else {
succ.left = null;
sum += node.val;
node.val = sum;
node = node.left;
}
}
}
return root;
}
private TreeNode getSuccessor(TreeNode node) {
TreeNode succ = node.right;
while(succ != null && succ.left != null) {
succ = succ.left;
}
return succ;
}