分治

156 阅读1分钟

⭐⭐241. 为运算表达式设计优先级

一开始的想法是计算好 a +/-/* b 再将结果放回原字符串,再递归地计算字符串,但这样会带来负号的问题。
应当利用分治思想:若遇到运算符,则把表达式按此运算符分为左右两部分,再递归计算左右两部分。递归的最底层为单个数字,每层递归结果均保存在 list 中并返回上一层。(代码书写不熟练)

⭐95. 不同的二叉搜索树 I & II

I

题目描述: 给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种?

算法:
定义两个函数:
G(n): 长度为 n 的序列的不同二叉搜索树个数。
F(i, n): 以 i 为根的不同二叉搜索树个数。

举例而言,F(3, 7),以 3 为根的不同二叉搜索树个数。为了以 3 为根从序列 [1, 2, 3, 4, 5, 6, 7] 构建二叉搜索树,我们需要从左子序列 [1, 2] 构建左子树,从右子序列 [4, 5, 6, 7] 构建右子树,然后将它们组合(即笛卡尔积)。 即:F(n, i)=\ G(i - 1) \cdot G(n - i)

可遍历每个数字 i 求得递推公式: G(n)=\sum_{i = 1}^{n} G(i - 1) \cdot G(n - i),此递推关系的解为卡特兰数(组合数学)。

参考

II

遍历每个数字 i,将该数字作为树根,1 ... (i-1) 序列将成为左子树,(i+1) ... n 序列将成为右子树。
这样,我们就有了树根 i 和可能的左子树、右子树的列表。最后一步,对两个列表循环,将左子树和右子树连接在根上。