leetcode

    xiaoxiao2021-03-25  132

    题意:

    给一个数n,返回所有能存储1到n的二叉查找树。

    分析:

    这是个好题,应该考虑深度优先搜索或者动态规划。

    递归好理解:

    遍历1到n每个数做结点。

    对于每一个根节点,将左边的结点能构造出的的所有树 以及 将右边的结点能构造出的所有树 求其笛卡尔积:即双重循环遍历。

    那么,怎么得到呢?递归,传的参数应该就是一串数,递归中又遍历这串数.......

    /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public List<TreeNode> generateTrees(int n) { if(n == 0) return new ArrayList<>(); return trees(1, n); } private List<TreeNode> trees(int start, int end){ List<TreeNode> roots = new ArrayList<>(); if(start > end){ roots.add(null); return roots; } for(int rootval=start; rootval<=end; rootval++){ //遍历n个数,每个都可能做根结点 List<TreeNode> lefttrees = trees(start, rootval-1); List<TreeNode> righttrees = trees(rootval+1, end); //左子树右子树的情况由于不是动态规划,没有存储,所以需要递归生成 for(TreeNode lefttree : lefttrees){ for(TreeNode righttree : righttrees){ TreeNode root = new TreeNode(rootval); root.left = lefttree; root.right = righttree; roots.add(root); } } } return roots; } }

    算法的思想是一样的,注意要右边的结点加值即可(注意需要重新构造)

    1 2 3 4 5 6 7

    对于3作为根节点左子树的形状先忽略,但肯定是12来组成

    对于3作为根节点右子树的形状先忽略,但肯定是4567来构成

    所以我们的dp数组里面存储的应该是List<TreeNode>  因为每N个结点有多种不同的构造形状。

    所以:

    3的左子树就是 dp[ 2 ]的所有

    3的右子树就是dp[ 4 ]的所有,但是注意,dp[ 3 ]里存储的是 1  2  3 4而不是 4  5  6  7,所以不能直接赋值,需要构造。

    /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public static List<TreeNode> generateTrees(int n) { List<TreeNode>[] dp = new List[n + 1]; dp[0] = new ArrayList<TreeNode>(); if (n == 0) { return dp[0]; } dp[0].add(null); for (int i = 1; i <= n; i++) { dp[i] = new ArrayList<TreeNode>(); //n个数是的所有情况 for (int rootval = 1; rootval <= i; rootval++) { //每个数都可能做根结点 int leftnum = rootval - 1; int rightnum = i - rootval; for (TreeNode left : dp[leftnum]) { for (TreeNode right : dp[rightnum]) { TreeNode root = new TreeNode(rootval); root.left = left; root.right = addVal(right, leftnum + 1); dp[i].add(root); } } } } return dp[n]; } private static TreeNode addVal(TreeNode root, int val) { if (root == null) { return null; } TreeNode node = new TreeNode(root.val + val); //对每个结点的操作应该是重新构造,否则会改变本身存储的内容 node.left = addVal(root.left, val); node.right = addVal(root.right, val); return node; } }

    转载请注明原文地址: https://ju.6miu.com/read-20154.html

    最新回复(0)