236 二叉树的最近公共祖先 https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/
105 从前序与中序遍历序列构造二叉树 https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
77 组合 https://leetcode-cn.com/problems/combinations/
46 全排列 https://leetcode-cn.com/problems/permutations/
47 全排列 II https://leetcode-cn.com/problems/permutations-ii/

二叉树的最近公共祖先

https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/

  1. /**
  2. * Definition for a binary tree node.
  3. * public class TreeNode {
  4. * int val;
  5. * TreeNode left;
  6. * TreeNode right;
  7. * TreeNode(int x) { val = x; }
  8. * }
  9. */
  10. class Solution {
  11. public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
  12. if(root == null || root == p || root == q){
  13. return root;
  14. }
  15. TreeNode left = lowestCommonAncestor(root.left,p,q);
  16. TreeNode right = lowestCommonAncestor(root.right,p,q);
  17. //当 left 和 right 同时为空:说明root的左 / 右子树中都不包含 p,q ,返回 null;
  18. if( left == null && right == null ){
  19. return null;
  20. }
  21. /*
  22. 当 left 为空 ,right不为空 :p,q都不在 root 的左子树中,直接返回 right 。具体可分为两种情况:
  23. 1、 p,q 其中一个在 root的 右子树 中,此时 right 指向 pp(假设为 p );
  24. 2、 p,q两节点都在 root 的 右子树 中,此时的 right 指向 最近公共祖先节点 ;
  25. */
  26. if( left == null ){
  27. return right;
  28. }
  29. //当 left不为空 , right为空 :与情况 上面. 同理;
  30. if(right == null){
  31. return left;
  32. }
  33. //当 left 和 right 同时不为空 :说明 p, q分列在 root 的 异侧 (分别在 左 / 右子树),因此 root为最近公共祖先,返回 root;
  34. return root;
  35. }
  36. }

从前序与中序遍历序列构造二叉树

https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

  1. /**
  2. * Definition for a binary tree node.
  3. * public class TreeNode {
  4. * int val;
  5. * TreeNode left;
  6. * TreeNode right;
  7. * TreeNode(int x) { val = x; }
  8. * }
  9. */
  10. class Solution {
  11. public TreeNode buildTree(int[] preorder, int[] inorder) {
  12. int len = preorder.length;
  13. Map<Integer,Integer> map = new HashMap<Integer,Integer>();
  14. for (int i = 0; i < len; i++) {
  15. map.put(inorder[i],i);
  16. }
  17. return buildTree(preorder,0,len - 1,0,len - 1,map);
  18. }
  19. /**
  20. *
  21. * @param preorder 前序遍历序列
  22. * @param preorder_left 前序遍历序列子区间的左边界,可以计算出来
  23. * @param preorder_right 前序遍历序列子区间右边界,可以计算出来
  24. * @param inorder_left 中序遍历序列子区间左边界,可以计算出来
  25. * @param inorder_right 中序遍历序列子区间右边界,可以计算出来
  26. * @param map 在中序遍历序列里,数值与下标对应关系
  27. * @return
  28. */
  29. private TreeNode buildTree(int[] preorder, int preorder_left, int preorder_right, int inorder_left, int inorder_right, Map<Integer,Integer> map) {
  30. if( preorder_left > preorder_right){
  31. return null;
  32. }
  33. //前序遍历中的第一个节点就是根节点
  34. int preorder_root = preorder_left;
  35. //在中序遍历中定位根节点,在中序的序列中找到对应的根节点的下标位置
  36. int inorder_root = map.get(preorder[preorder_root]);
  37. //建立根节点
  38. TreeNode root = new TreeNode(preorder[preorder_root]);
  39. //得到左子树中的节点数目
  40. int size_left_subtree = inorder_root - inorder_left;
  41. //递归的构造左子树
  42. root.left = buildTree(preorder,preorder_left + 1,preorder_left + size_left_subtree, inorder_left ,inorder_root - 1,map);
  43. //递归的构造右子树
  44. root.right = buildTree(preorder,preorder_left + size_left_subtree + 1,preorder_right,inorder_root+1,inorder_right,map);
  45. return root;
  46. }
  47. }

组合

https://leetcode-cn.com/problems/combinations/

全排列

https://leetcode-cn.com/problems/permutations/

全排列II

https://leetcode-cn.com/problems/permutations-ii/