## 暴力做法
由于需要将二叉搜索树进行排列,这种分步骤进行的想法很容易转换为回溯的思想。每一步即为从当前现有的数字中取出一个作为当前节点的选择,做出选择后即得到一个新的状态——当前二叉树。接下来即进入下一层,搜索左子树和右子树。如果左右子树不可行则回溯,重新分配下一个数字。
伪代码如下:
```java
private void backtrack(List currNums, TreeNode p) {
if (排列完整颗树) {
globalCnt++;
return;
}
for (Integer i : currNums) {
currNums.remove(i);
p.val = i;
if (将i赋给当前节点后,不满足BST)
continue;
backtrack(currNums, p.left);
backtrack(currNums, p.right);
currNums.add(i);
}
}
```
然而这里有几个问题需要解决,
\1. 如何遍历该二叉搜索树呢?因为BST的性质可能不同,一个办法是构造一颗节点大于等于n的满二叉树,如果节点值为-1,则表示当前节点没有使用;
\2. 如何判断排列完n个节点呢,可以加入一个参数n, 边计数;
\3. 如何快速判断当前节点加入值后,是否符合BST,这一点想要做到并不是那么容易的
可以看到,虽然回溯想法非常朴素,然而真的要实现并不是那么容易的。但是从回溯的想法中,我们实际上可以发现一些问题,有助于我们接下来的思考。
为什么回溯会做的这么艰难呢?第一点就是因为你需要注意,题目并不需要你找到所有可能的二叉树,而是计数问题。因此真正去构造一颗BST不是一个好想法,费时费力。
然而有人会问了,那如果不真实构造BST,我怎么去检查