Difficulty: 中等
给定一个整数 n,生成所有由 1 … n 为节点所组成的 二叉搜索树 。
示例:
输入:3
输出:
[
[1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]
]
解释:
以上的输出对应以下 5 种不同结构的二叉搜索树:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
提示:
0 <= n <= 8
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
/*思路:
1. 就是把L,R看成是二叉搜索树中序遍历的左右边界
2.枚举每个点为root,递归两边。返回的集合中都是合法的左子树或者右子树
3.root和集合中的左右子树分别拼接一下即可
*/
class Solution {
public List<TreeNode> generateTrees(int n) {
if(n < 1) return new ArrayList<>();
return dfs(1,n);
}
public List<TreeNode> dfs(int L, int R){
List<TreeNode> res = new ArrayList<>();
if(L > R){
res.add(null);
return res;
}
for(int i=L; i<=R; i++){ //分别为根节点
List<TreeNode> left = dfs(L, i-1);
List<TreeNode> right = dfs(i+1, R);
for(TreeNode l: left){
for(TreeNode r: right){
TreeNode head = new TreeNode(i);
head.left = l;
head.right = r;
res.add(head);
}
}
}
return res;
}
}
Difficulty: 中等
给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?
示例:
输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
当n = 3时:
class Solution {
public int numTrees(int n) {
if(n<=0) return 0;
if(n == 1) return 1;
if(n == 2) return 2;
int[] dp = new int[n+1];
dp[0] = 1;
dp[1] = 1;
dp[2] = 2;
for(int i=3; i<=n; i++){
dp[i] = 0;
for(int j=0; j<=i-1; j++){
dp[i] += dp[j]*dp[i-1-j];
}
}
return dp[n];
}
}
Difficulty: 困难
给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的。
示例 1:
输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
输出: true
示例 2:
输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
输出: false
class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
int len1 = s1.length(), len2 = s2.length(), len3 = s3.length();
if(len3<0 || (len1+len2)!=len3) return false;
boolean[][] dp = new boolean[len1+1][len2+1];
dp[0][0] = true;
for(int i=0; i<=len1; i++){
for(int j=0; j<=len2; j++){
if(i==0 && j==0) continue;
else if(i==0){
if(s2.charAt(j-1) == s3.charAt(j-1)) dp[0][j] = dp[0][j-1];
}
else if(j==0){
if(s1.charAt(i-1) == s3.charAt(i-1)) dp[i][0] = dp[i-1][0];
}
else{
dp[i][j] = (s1.charAt(i-1)==s3.charAt(i+j-1) && dp[i-1][j]) ||
(s2.charAt(j-1)==s3.charAt(i+j-1) && dp[i][j-1]);
}
}
}
return dp[len1][len2];
}
}
Difficulty: 中等
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
示例 1:
输入:
2
/ \
1 3
输出: true
示例 2:
输入:
5
/ \
1 4
/ \
3 6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
根节点的值为 5 ,但是其右子节点值为 4 。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isValidBST(TreeNode root) {
List<Integer> num = new ArrayList<>();
List<TreeNode> stack = new ArrayList<>();
TreeNode cur = root;
while(cur!=null || !stack.isEmpty()){
if(cur != null){
stack.add(cur);
cur = cur.left;
}
else{
cur = stack.remove(stack.size()-1);
if(!num.isEmpty() && num.get(num.size()-1) >= cur.val)
return false;
num.add(cur.val);
cur = cur.right;
}
}
return true;
}
}
Difficulty: 困难
二叉搜索树中的两个节点被错误地交换。
请在不改变其结构的情况下,恢复这棵树。
示例 1:
输入: [1,3,null,null,2]
1
/
3
\
2
输出: [3,1,null,null,2]
3
/
1
\
2
示例 2:
输入: [3,1,4,null,null,2]
3
/ \
1 4
/
2
输出: [2,1,4,null,null,3]
2
/ \
1 4
/
3
进阶:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
//交换只需要交换两个值就可以了
class Solution {
public void recoverTree(TreeNode root) {
if(root == null) return;
List<TreeNode> nodeList = new ArrayList<>();
midSort(root, nodeList);
int i1 = 0, i2 = 0; //需要交换的位置
int count = 0; //逆序对的个数
int len = nodeList.size();
for(int i=0; i<len; i++){
if(i<len-1 && nodeList.get(i).val>nodeList.get(i+1).val){
if(count == 0){
i1 = i;
i2 = i+1;
count++;
}
else{
i2 = i+1;
break;
}
//System.out.println(i1+","+i2);
}
}
//System.out.println(nodeList.get(i1).val +","+ nodeList.get(i2).val);
//交换值
int temp = nodeList.get(i1).val;
nodeList.get(i1).val = nodeList.get(i2).val;
nodeList.get(i2).val = temp;
}
//中序遍历
public void midSort(TreeNode root, List<TreeNode> nodeList){
if(root == null) return;
midSort(root.left, nodeList);
nodeList.add(root);
midSort(root.right, nodeList);
}
}