小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
二叉树
前序遍历
顺序是遍历根节点, 左子树, 右子树
class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
TreeNode() {
}
TreeNode(int val) {
this.val = val;
}
}
/**
* 递归前序遍历 时间复杂度O(N) 空间复杂度O(H)
*/
public void preOrder(TreeNode root, List<Integer> ans) {
if (root != null) {
ans.add(root.val);
preOrder(root.left, ans);
preOrder(root.right, ans);
}
}
/**
* 栈的前序遍历 时间复杂度O(N) 空间复杂度O(H)
*/
public List<Integer> preOrderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
List<Integer> ans = new ArrayList<>();
while (root != null || !stack.isEmpty()) {
while (root != null) {
stack.push(root);
ans.add(root.val);
root = root.left;
}
root = stack.peek();
stack.pop();
root = root.right;
}
return ans;
}
二叉搜索树
题目: 给定一棵二叉树,判断是否是二叉搜索树。
private boolean f;
public boolean isValidBST(TreeNode root) {
f = true;
preOrder(root, Long.MIN_VALUE, Long.MAX_VALUE);
return f;
}
private void preOrder(TreeNode root, Long min, Long max) {
if (root == null || !f) {
return;
}
if (!(min < root.val && max > root.val)) {
f = false;
return;
}
preOrder(root.left, min, Long.valueOf(root.val));
preOrder(root.right, Long.valueOf(root.val), max);
}
目标和的所有路径
题目: 给定一棵二叉树, 一个目标值,输出所有路径,需要满足根节点到叶子节点之和等于给定的目标值
输入:target = 9
输出:[[5,4], [5,3,1]]
private List<List<Integer>> ans = new ArrayList<>();
public List<List<Integer>> pathSum(TreeNode root, int sum) {
List<Integer> path = new ArrayList<>();
backtrace(root, path, 0, sum);
return ans;
}
private void backtrace(TreeNode root, List<Integer> path, int sum, int target) {
if (root == null) {
return;
}
sum += root.val;
path.add(root.val);
if(root.left == null && root.right == null){
if(sum == target){
ans.add(new ArrayList<>(path));
}
} else {
backtrace(root.left, path, sum, target);
backtrace(root.right, path, sum, target);
}
path.remove(path.size()-1);
}
中序遍历
遍历从左子树,根节点,右子树开始遍历
public List<Integer> inorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
List<Integer> result = new ArrayList<>();
if(root != null || !stack.empty()){
while(root != null){
stack.push(root);
root = root.left;
}
root = stack.peek();
stack.pop();
result.add(root.val);
root = root.right;
}
return result;
}
二叉搜索树
private boolean bst;
private Long preValue;
public boolean isValidBSTMid(TreeNode root) {
bst = true;
preValue = Long.MIN_VALUE;
midOrder(root);
return bst;
}
private void midOrder(TreeNode root) {
if(!bst){
return;
}
if(root != null){
midOrder(root.left);
if(preValue >= root.val){
bst = false;
return;
}
preValue = Long.valueOf(root.val);
midOrder(root.right);
}
}
删除二叉搜索数的节点
题目: 删除二叉搜索树的指定结点。返回删除之后的根结点。
private void swapValue(TreeNode a, TreeNode b){
int t = a.val;
a.val = b.val;
b.val = t;
}
public TreeNode deleteNode(TreeNode root, int key){
if(root == null ){
return null;
}
if(key < root.val){
root.left = deleteNode(root.left, key);
} else if(key > root.val){
root.right = deleteNode(root.right, key);
}else {
if(root.left == null && root.right == null){
return null;
} else if(root.left != null){
TreeNode large = root.left;
while(large.right != null){
large = large.right;
}
swapValue(root, large);
root.left = deleteNode(root.left, key);
} else if(root.right != null){
TreeNode small = root.right;
while(small.left != null){
small = small.left;
}
swapValue(root, small);
root.right = deleteNode(root.right, key);
}
}
return root;
}
后序处理
左子树 右子树 根节点
private void preOrderAfter(TreeNode root, List<Integer> result) {
if (root != null) {
preOrderAfter(root.left, result);
preOrderAfter(root.right, result);
result.add(root.val);
}
}
public List<Integer> postorderTraversal(TreeNode root){
List<Integer> resultList = new ArrayList<>();
TreeNode pre = null;
Stack<TreeNode> stack = new Stack<>();
while(!stack.isEmpty() || root != null){
while(root != null){
stack.push(root);
root = root.left;
}
root = stack.peek();
if(root.right == null || root.right == pre){
resultList.add(root.val);
stack.pop();
pre = root;
root = null;
} else {
root = root.right;
}
}
return resultList;
}
最低公共祖先
TreeNode res = null;
private int postOrder(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return 0;
}
int lcnt = postOrder(root.left, p, q);
int rcnt = postOrder(root.right, p, q);
if(lcnt ==1 && rcnt ==1){
res = root;
} else if(lcnt ==1 || rcnt ==1) {
if(root ==p || root==q){
res = root;
}
}
return lcnt + rcnt + ((root==p||root==q)? 1:0);
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p , TreeNode q){
postOrder(root, p, q);
return res;
}