//f(i)表示以i为根的二叉树的搜索树个数,所以n的全部的搜索树个数G(n)
// G(n)=f(1)+f(2)+f(3)+f(4)+...+f(n)
// 当 i 为根节点时,其左子树节点个数为 i-1 个,右子树节点为 n-i,则左子节点二叉排序树的个数*右子节点二叉排序树的个数就是当i为根节点时候二叉排序树的个数
// f(i) = G(i−1)∗G(n−i)
// 综合两个公式可以得到 卡特兰数 公式
//G(n)=G(0)∗G(n−1)+G(1)∗(n−2)+...+G(n−1)∗G(0)
class Solution {
public int numTrees(int n) {
int[] G = new int[n+1];
G[0] = 1;
G[1] = 1;
//反正一个i一个j尝试的方式比着上面公式写进去
for (int i = 2; i < n + 1; i++) {
for (int j = 1; j < i + 1; j++) {
G[i] += G[j - 1] * G[i - j];
}
}
return G[n];
}
}
/**
* 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 TreeNode buildTree(int[] preorder, int[] inorder) {
//两个数长度一样,也一个的长度就行
if (preorder.length == 0) return null;
TreeNode root = new TreeNode(preorder[0]);
for (int i = 0; i < preorder.length; i++) {
if (preorder[0] == inorder[i]) {
root.left = buildTree(Arrays.copyOfRange(preorder, 1, i + 1),
//类似的copyOfRange这种方法都是包含前不包含尾
Arrays.copyOfRange(inorder, 0, i));
root.right = buildTree(Arrays.copyOfRange(preorder, i + 1, preorder.length),
Arrays.copyOfRange(inorder, i + 1, inorder.length));
break;
}
}
return root;
}
}
//先去重,在从最小的那个数开始找保存最长的连续序列
class Solution {
public int longestConsecutive(int[] nums) {
HashSet<Integer> set = new HashSet<>();
for (int x : nums) {
set.add(x);
}
int res = 0;
for (int x : set) {
//从最小的开始找
if (!set.contains(x - 1)) {
//把x拿出来,不操作原set中数据
int num = x;
int curMaxXL = 1;
//找比他大的记录为连续的序列,记录连续序列长度
while (set.contains(num + 1)) {
num++;
curMaxXL++;
}
res = Math.max(res, curMaxXL);
}
}
return res;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
// class Solution {
// public ListNode sortList(ListNode head) {
// return sortList(head, null);
// }
// //归并排序
// //方法重载
// public ListNode sortList(ListNode head, ListNode tail) {
// //不进入这个递归的情况
// if (head == null) return head;
// //递归结束的条件
// if (head == tail)
// //递归要做什么,返回什么
// //要给表排序,分而治之,归并排序
// ListNode slow = head;
// ListNode fast = head;
// //快的到了,慢的走到一半
// //避免空指针,好像还是不用xxx.next作为判断条件比较多
// while (fast != tail) {
// slow = slow.next;
// fast = fast.next;
// if (fast != tail) {
// fast = fast.next;
// }
// }
// ListNode mid = slow;
// ListNode l1 = sortList(head, mid);
// ListNode l2 = sortList(mid, tail);
// ListNode sorted = merge(l1, l2);
// return sorted;
// }
// }
class Solution {
public ListNode sortList(ListNode head) {
return sortList(head, null);
}
public ListNode sortList(ListNode head, ListNode tail) {
if (head == null) {
return head;
}
//分而治之,归并排序是分到一个为止,head后面是tail,然后让其变成真正的null
if (head.next == tail) {
head.next = null;
return head;
}
ListNode slow = head, fast = head;
//不使用fast.next.next的原因是这样可以更好的划分,比如4个链表的时候把前2个划出去
while (fast != tail) {
slow = slow.next;
fast = fast.next;
if (fast != tail) {
fast = fast.next;
}
}
ListNode mid = slow;
//tail是当作null处理的。所以是这么传入,其实前面的l1中mid是null
ListNode l1 = sortList(head, mid);
ListNode l2 = sortList(mid, tail);
ListNode sorted = merge(l1, l2);
return sorted;
}
public ListNode merge(ListNode l1, ListNode l2) {
if (l1 == null) return l2;
if (l2 == null) return l1;
ListNode pre = new ListNode(-1);
ListNode cur = pre;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
cur.next = l1;
l1 = l1.next;
} else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
cur.next = l1 == null ? l2 : l1;
return pre.next;
}
}
/**
* 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 flatten(TreeNode root) {
List<TreeNode> list = new ArrayList<TreeNode>();
Deque<TreeNode> stack = new LinkedList<>();
while (root != null || !stack.isEmpty()) {
if (root != null) {
stack.push(root);
list.add(root);
root = root.left;
} else {//root==null&&stack不为空
root = stack.pop();
root = root.right;
}
}
for(int i = 1; i < list.size(); i++) {
TreeNode pre = list.get(i - 1), cur = list.get(i);
pre.left = null;
pre.right = cur;
}
}
//输出显示都是从上到下从左到右的层序遍历
}