算法:树
原创
©著作权归作者所有:来自51CTO博客作者是丹凤呀的原创作品,请联系作者获取转载授权,否则将追究法律责任
树的最大路径和
https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/ 思路:
递归+遍历
最大路径和
按照一个树 比如【a,b,c】 实际是三选一问题:b+root 与c+root 或者 b+c+root
maxSum 用于更新最大和,treeMaxSum
int maxSum= Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
treeMaxSum(root);
return maxSum;
}
public int treeMaxSum(TreeNode root){
if (root==null) return 0;
int left=Math.max(0,treeMaxSum(root.left));
int right=Math.max(0,treeMaxSum(root.right));
int tempMax=Math.max(left,right);
tempMax=Math.max(tempMax,left+right);
maxSum= Math.max(maxSum,tempMax+root.val);
return Math.max(left,right)+root.val;
}
根据前序 中序遍历结果还原二叉树
https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
思路:
遍历 + 递归
前序:根左右
中序:左根右
根据中序遍历 可以分出左子树与右子树, 记录根的下标记 rootIndex,左子树个数为rootIndex 前的个数leftNum,从而知道前序遍历中的start+leftNum+1开始是左子树,后面的全部是右子树。递归调用
public TreeNode buildTree(int[] preorder, int[] inorder) {
return buildTree(preorder, 0, preorder.length , inorder, 0, inorder.length );
}
public TreeNode buildTree(int[] preorder, int p_start, int p_end,
int[] inorder, int i_start, int i_end) {
if (p_start == p_end) {
return null;
}
TreeNode treeNode = new TreeNode(preorder[p_start]);
int rootIndex = 0;
for (int i = i_start; i < i_end; i++) {
if (inorder[i] == preorder[p_start]) {
rootIndex = i;
}
}
int leftNum = rootIndex - i_start;
treeNode.left = buildTree(preorder, p_start+1, p_start +1+ leftNum , inorder, i_start, rootIndex );
treeNode.right = buildTree(preorder, p_start +1+ leftNum, p_end, inorder, rootIndex + 1, i_end);
return treeNode;
}
树按层遍历(BFS)
规律: 利用队列 ,看作图的遍历
扩展: 可以求深度
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> list = new ArrayList<>();
if (root==null) return list;
Deque<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> levelResult = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode cur = queue.poll();
levelResult.add(cur.val);
if (cur.left != null) {
queue.add(cur.left);
}
if (cur.right != null) {
queue.add(cur.right);
}
}
list.add(levelResult);
}
return list;
}
树按深度遍历
非递归,利用栈实现
//深度优先遍历
List<TreeNode> treeList ;
public List<TreeNode> dfs(TreeNode root) {
treeList = new ArrayList<>();
if(root==null) {
return null;
}
Stack<TreeNode> myStack=new Stack<>();
myStack.add(root);
while(!myStack.isEmpty()) {
TreeNode node=myStack.pop(); //弹出栈顶元素
//System.out.print(node.value+" ");
treeList.add(node);
//向栈中先压入右子树,在压入左子树。这样出栈时,先出左子树再出右子树.也就是,先遍历左边,后遍历右边
if(node.right!=null) {
myStack.push(node.right);
}
if(node.left!=null) {
myStack.push(node.left);
}
}
return treeList;
}
递归
<TreeNode> treeNodeList = new ArrayList<>();;
public List<TreeNode> dfsRec(TreeNode root) {
if (root == null) {
return null;
}
treeNodeList.add(root);
//System.out.print(root.value+" ");
dfsRec(root.left);
dfsRec(root.right);
return treeNodeList;
}