bst中序遍历的下个节点
TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
if (!root || !p) return NULL;
// bst的中序遍历是个有序数组,这题相当于要找第一个>p.val的节点
// 类似二分搜索,root就是二分搜索中的mid
TreeNode *succ = NULL;
while (root) {
if (root->val > p->val) { // root作候选,看左边有没更小的
succ = root;
root = root->left;
} else { // root值太小,排除root和左子树
root = root->right;
}
}
return succ;
}
bst中删除值为key的节点
TreeNode* deleteNode(TreeNode* root, int key) {
if (!root) return nullptr;
if (key < root->val) {
root->left = deleteNode(root->left, key);
return root;
}
if (key > root->val) {
root->right = deleteNode(root->right, key);
return root;
}
if (!root->right) {
auto left = root->left;
delete root;
return left;
}
// 找到后继节点
auto succ = root->right;
while (succ->left) {
succ = succ->left;
}
succ->left = root->left;
auto right = root->right;
delete root;
return right;
}
已知数组从左到右扫描所得的bst样子,求对应数组的可能排列数
class Solution {
vector<vector<int>> C;
const int MOD = 1e9 + 7;
public:
int numOfWays(vector<int>& nums) {
const int N = nums.size();
// 组合数nCk为杨辉三角中C[n][k]
C = vector<vector<int>>(N, vector<int>(N));
C[0][0] = 1;
for (int i = 1; i < N; i++) {
C[i][0] = 1;
for (int j = 1; j <= i; j++) {
C[i][j] = (C[i-1][j-1] + C[i-1][j]) % MOD;
}
}
return ways(nums) - 1; // 其他排列
}
int ways(vector<int>& nums) {
const int N = nums.size();
if (N <= 1) return 1;
vector<int> left, right;
for (int i = 1; i < N; i++) {
if (nums[i] < nums[0]) left.push_back(nums[i]);
else right.push_back(nums[i]);
}
return weave(left, right);
}
int weave(vector<int>& A, vector<int>& B) {
// 左右两数组交织,可保持二叉树不变
int nCk = C[A.size() + B.size()][A.size()];
long left = ways(A), right = ways(B);
return (((left * right) % MOD) * nCk) % MOD;
}
};
已知数组从左到右扫描所得的bst样子,求对应数组的所有可能排列
根节点是数组首元素,左子树是小于它的元素们、右子树是大于它的元素们,但左右子树的元素哪个先对应到数组元素不确定。左右子树分别对应的数组有多种排列,取左子树的一组排列{a1, a2, a3, ...}和右子树的一组排列{b1, b2, b3, ...},怎么由它们得到原数组的排列?用"交织"操作:保持组内的相对次序不变,组间的次序(先插入左子树元素还是右子树元素)无所谓。递归:取{a1},后面是{a2, a3, ...}和{b1, b2, b3, ...}的交织;或取{b1},后面是{a1, a2, a3, ...}和{b2, b3, ...}的交织;当一组为空时,另一组直接拼上。见ctci p262。
// 简写起见,List指LinkedList<Integer>,List[]指ArrayList<LinkedList<Integer>>
void weaveLists(List prefix, List l1, List l2, List[] ans) {
if (l1.size() == 0 || l2.size() == 0) {
List list = prefix.clone();
list.add(l1);
list.add(l2);
ans.add(list);
return;
}
// l1取头放到prefix中,递归后还原
int f1 = l1.removeFirst();
prefix.addLast(f1);
weaveList(prefix, l1, l2, ans);
prefix.removeLast();
l1.addFirst(f1);
// l2一样处理
int f2 = l2.removeFirst();
prefix.addLast(f2);
weaveList(prefix, l1, l2, ans);
prefix.removeLast();
l2.addFirst(f2);
}
List[] allSequences(TreeNode node) {
List[] ans = new ArrayList<LinkedList<Integer>>();
if (!node) return ans;
List prefix = new LinkedList<Integer>();
prefix.add(node.data); // 根节点=>数组首元素
List[] leftSeq = allSequences(node.left);
List[] rightSeq = allSequences(node.right);
for (List left : leftSeq) {
for (List right : rightSeq) {
weaveList(prefix, left, right, ans);
}
}
return ans;
}