91. Decode Ways
recursion
class Solution {
public int numDecodings(String s) {
int[] dp=new int[s.length()];
Arrays.fill(dp,1);
return dfs(dp,s,0);
}
public int dfs(int[] dp,String s,int i){
if(i>=s.length()){
return 1;
}
if(dp[i]>1||dp[i]==0){
return dp[i];
}
if(s.charAt(i)=='0'){
return 0;
}
int res=dfs(dp,s,i+1);
if(i+1<s.length()&&(s.charAt(i)=='1'||(s.charAt(i)=='2'&&s.charAt(i+1)<='6'))){
res+=dfs(dp,s,i+2);
}
dp[i]=res;
return res;
}
}
for-loop
public int numDecodings(String s) {
int[] dp=new int[s.length()];
Arrays.fill(dp,1);
dp[s.length()-1]=s.charAt(s.length()-1)=='0'?0:1;
for(int i=s.length()-2;i>=0;i--){
if (s.charAt(i)=='0'){
dp[i]=0;
continue;
}
if(s.charAt(i)>'2'){
dp[i]=dp[i+1];
continue;
}
if(s.charAt(i)=='2'&&s.charAt(i+1)>'6'){
dp[i]=dp[i+1];
continue;
}
if(i+2>=s.length()){
dp[i]=dp[i+1]+1;
continue;
}
dp[i]=dp[i+1]+dp[i+2];
}
return dp[0];
}
95. Unique Binary Search Trees II*
public List<TreeNode> generateTrees(int n) {
List<TreeNode>[] res=new ArrayList[n+1];
res[0]= new ArrayList<>();
if (n==0){
return res[0];
}
res[0].add(null);
for (int i=1;i<=n;i++){
res[i]= new ArrayList<>();
for (int root=1;root<=i;root++){
int left=root-1;//左子树的长度
int right=i-root;//右子树的长度
for (var leftTree:res[left]){
for (var rightTree:res[right]){
TreeNode node=new TreeNode(root);
node.left=leftTree;
node.right=clone(rightTree,root);
res[i].add(node);
}
}
}
}
return res[n];
}
public TreeNode clone(TreeNode node,int offset){
if (node==null){
return null;
}
TreeNode target=new TreeNode(node.val+offset);
target.left=clone(node.left,offset);
target.right=clone(node.right,offset);
return target;
}
96. Unique Binary Search Trees
public int numTrees(int n) {
int[] dp=new int[n+1];
dp[1]=1;
if (n==1||n==0){
return 1;
}
dp[2]=2;
dp[0]=1;
for(int i=3;i<=n;i++){
int split=1;
while (split<=i){
dp[i]+=dp[split-1]*dp[i-split];
split++;
}
}
return dp[n];
}
98. Validate Binary Search Tree
class Solution {
public boolean isValidBST(TreeNode root) {
//卡边界值,要用long
return valiadateBST(root,Long.MIN_VALUE,Long.MAX_VALUE);
}
public boolean valiadateBST(TreeNode root,long left,long right){
if(root==null){
return true;
}
if(!(root.val>left&&root.val<right)){
return false;
}
return valiadateBST(root.left,left,root.val)&&valiadateBST(root.right,root.val,right);
}
}
*99. Recover Binary Search Tree
class Solution {
public static TreeNode abnormal1;
public static TreeNode abnormal2;
public static TreeNode prev;
public void recoverTree(TreeNode root) {
abnormal1=null;
abnormal2=null;
prev=null;
inOrder(root);
swap(abnormal1,abnormal2);
}
// in order traverse
public void inOrder(TreeNode root){
if (root==null){
return;
}
inOrder(root.left);
if (prev==null){
prev=root;
}
else{
if (root.val<prev.val){
abnormal1=root;
if (abnormal2==null){
abnormal2=prev;
}
}
prev=root;
}
inOrder(root.right);
}
public void swap(TreeNode a,TreeNode b){
int tmp=a.val;
a.val=b.val;
b.val=tmp;
}
}
100. Same Tree
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p==null&&q==null){
return true;
}
if (p==null||q==null){
return false;
}
if (p.val!=q.val){
return false;
}
return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
}
101. Symmetric Tree
public boolean isSymmetric(TreeNode root) {
return dfs(root.left,root.right);
}
public boolean dfs(TreeNode left,TreeNode right){
if(left==null&&right==null){
return true;
}
if(left==null||right==null){
return false;
}
return (left.val==right.val)&&dfs(left.left,right.right)&&dfs(left.right,right.left);
}
104. Maximum Depth of Binary Tree(Solved)
class Solution {
public int maxDepth(TreeNode root) {
return findMaxDepthRecursively(root);
}
public int findMaxDepthRecursively(TreeNode root){
if (root==null){
return 0;
}
int leftHeight=findMaxDepthRecursively(root.left)+1;
int rightHeight=findMaxDepthRecursively(root.right)+1;
return Math.max(leftHeight,rightHeight);
}
}
105. Construct Binary Tree from Preorder and Inorder Traversal
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder.length==0 ||inorder.length==0){
return null;
}
TreeNode midNode=new TreeNode(preorder[0]);
// https://www.geeksforgeeks.org/find-the-index-of-an-array-element-in-java/
int midIndex=IntStream.range(0,preorder.length).filter(i->midNode.val==inorder[i]).findFirst().orElse(-1);
// https://www.geeksforgeeks.org/java-util-arrays-copyofrange-java/
midNode.left=buildTree(Arrays.copyOfRange(preorder,1,midIndex+1),Arrays.copyOfRange(inorder,0,midIndex));
midNode.right=buildTree(Arrays.copyOfRange(preorder,midIndex+1,preorder.length),Arrays.copyOfRange(inorder,midIndex+1,inorder.length));
return midNode;
}
106. Construct Binary Tree from Inorder and Postorder Traversal
class Solution {
public static HashMap<Integer,Integer> inorderNodesIdx=new HashMap<>();
public static int postIdx;
public TreeNode buildTree(int[] inorder, int[] postorder) {
inorderNodesIdx.clear();
for (int i=0;i<inorder.length;i++){
inorderNodesIdx.put(inorder[i],i);
}
postIdx=postorder.length-1;
return buildSubTree(inorder,postorder,0,inorder.length-1);
}
public TreeNode buildSubTree(int[] in,int [] post, int inorderStartIdx,int inorderEndIdx){
if (inorderStartIdx>inorderEndIdx){
return null;
}
var nodeVal=post[postIdx];
postIdx--;
TreeNode node=new TreeNode(nodeVal);
if (inorderStartIdx==inorderEndIdx){
return node;
}
int divideIdx=inorderNodesIdx.get(nodeVal);
//注意执行顺序是中->右->左
node.right=buildSubTree(in,post,divideIdx+1,inorderEndIdx);
node.left=buildSubTree(in,post,inorderStartIdx,divideIdx-1);
return node;
}
}
107. Binary Tree Level Order Traversal II
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> res=new ArrayList<>();
Queue<TreeNode> queue=new LinkedList<>();
Queue<TreeNode> curr=new LinkedList<>();
if (root==null){
return res;
}
queue.add(root);
while (!queue.isEmpty()){
curr.clear();
List<Integer> currRes=new ArrayList<>();
while (!queue.isEmpty()){
TreeNode node=queue.poll();
currRes.add(node.val);
if (node.left!=null){
curr.add(node.left);
}
if (node.right!=null){
curr.add(node.right);
}
}
res.add(currRes);
queue.addAll(curr);
}
Collections.reverse(res);
return res;
}
*108. Convert Sorted Array to Binary Search Tree
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return inorderBuild(nums,0,nums.length-1);
}
public TreeNode inorderBuild(int[] nums,int left,int right){
if (left>right){
return null;
}
int mid=(left+right)>>1;
TreeNode curr=new TreeNode(nums[mid]);
curr.left=inorderBuild(nums,left,mid-1);
curr.right=inorderBuild(nums,mid+1,right);
return curr;
}
}
*109. Convert Sorted List to Binary Search Tree
class Solution {
public static ListNode globalHead;
public TreeNode sortedListToBST(ListNode head) {
globalHead=head;
int length=getLength(head);
return buildTree(0,length-1);
}
public int getLength(ListNode head){
int height=0;
while (head!=null){
head=head.next;
height++;
}
return height;
}
public TreeNode buildTree(int left,int right){
if (left>right){
return null;
}
int mid=(left+right)>>1;
TreeNode node=new TreeNode();
node.left=buildTree(left,mid-1);
node.val=globalHead.val;
globalHead=globalHead.next;
node.right=buildTree(mid+1,right);
return node;
}
}
110. Balanced Binary Tree
class Solution {
public boolean isBalanced(TreeNode root) {
return judgeBalance(root);
}
public boolean judgeBalance(TreeNode root){
if(root==null){
return true;
}
int leftHeight=getHeight(root.left);
int rightHeight=getHeight(root.right);
if(Math.abs(rightHeight-leftHeight)<=1&&judgeBalance(root.left)&&judgeBalance(root.right)){
return true;
}
return false;
}
public int getHeight(TreeNode root){
if (root == null)
return 0;
return 1+ Math.max(getHeight(root.left),getHeight(root.right));
}
}
111. 二叉树的最小深度
class Solution {
public int minDepth(TreeNode root) {
return minHeight(root);
}
public int minHeight(TreeNode node){
if (node==null){
return 0;
}
if (node.left==null&&node.right!=null){
return 1+minHeight(node.right);
}
if (node.right==null&&node.left!=null){
return 1+minHeight(node.left);
}
return Math.min( minHeight(node.left),minHeight(node.right))+1;
}
}
112. Path Sum
class Solution {
public static boolean tag=false;
public boolean hasPathSum(TreeNode root, int targetSum) {
tag=false;
bfs(root,targetSum,0);
return tag;
}
public void bfs(TreeNode root,int targetSum,int currSum){
if(root==null){
return ;
}
currSum+=root.val;
if(root.left==null&&root.right==null&&targetSum==currSum){
tag=true;
return ;
}
if(root.left!=null){
bfs(root.left,targetSum,currSum);
}
if(root.right!=null){
bfs(root.right,targetSum,currSum);
}
return ;
}
}
113. Path Sum II
class Solution {
public static List<List> res=new ArrayList<>();
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
res.clear();
if(root==null&&targetSum==0){
return res;
}
ArrayList<Integer> currRes=new ArrayList<>();
bfs(root,targetSum,0,currRes);
return res;
}
public void bfs(TreeNode root,int targetSum,int currSum,ArrayList<Integer> currRes){
if(root==null){
return;
}
currRes.add(root.val);
currSum+=root.val;
if(currSum==targetSum && root.left==null&&root.right==null){
res.add((ArrayList<Integer>)currRes.clone());
}
if(root.left!=null){
bfs(root.left,targetSum,currSum,currRes);
}
if(root.right!=null){
bfs(root.right,targetSum,currSum,currRes);
}
// System.out.println()
currRes.remove(currRes.size()-1);
// targetSum-=root.val;
}
}
*114. Flatten Binary Tree to Linked List
class Solution {
public void flatten(TreeNode root) {
bfs(root);
}
public TreeNode bfs(TreeNode root) {
if(root==null){
return null;
}
TreeNode leftTail=bfs(root.left);
TreeNode rightTail=bfs(root.right);
if(leftTail!=null){
leftTail.right=root.right;
root.right=root.left;
root.left=null;
}
if(rightTail!=null){
return rightTail;
}
if(leftTail!=null){
return leftTail;
}
return root;
}
}
115. Distinct Subsequences
class Solution {
public static String source;
public static String target;
public int numDistinct(String s, String t) {
source=s;
target=t;
//foreach 遍历更快
int[][] dp=new int[s.length()][t.length()];
for (int i=0;i<s.length();i++){
Arrays.fill(dp[i],-1);
}
return bfs(dp,0,0);
}
public int bfs(int[][] dp,int i,int j){
if (j==target.length()){
return 1;
}
if (i==source.length()){
return 0;
}
if (dp[i][j]!=-1){
return dp[i][j];
}
if (source.charAt(i)==target.charAt(j)){
dp[i][j]=bfs(dp,i+1,j+1)+bfs(dp,i+1,j);
}
else{
dp[i][j]=bfs(dp,i+1,j);
}
return dp[i][j];
}
}
*116. Populating Next Right Pointers in Each Node
bfs
public Node connect(Node root) {
Node curr=root;
Node next=null;
if (root!=null){
next=root.left;
}
while (curr!=null&&next!=null){
curr.left.next=curr.right;
if (curr.next!=null){
curr.right.next=curr.next.left;
}
curr=curr.next;
if (curr==null){
curr=next;
next=curr.left;
}
}
return root;
}
Populating Next Right Pointers in Each Node II
使用队列,空间超出
public Node connect(Node root) {
if (root==null){
return null;
}
Queue<Node> nodes=new LinkedList<>();
nodes.add(root);
Queue<Node> nextNodes=new LinkedList<>();
while (!nodes.isEmpty()){
nextNodes.clear();
Node prev=null;
while (!nodes.isEmpty()){
Node curr=nodes.poll();
if (prev!=null){
prev.next=curr;
}
prev=curr;
if (curr.left!=null) {
nextNodes.add(curr.left);
}
if (curr.right!=null) {
nextNodes.add(curr.right);
}
}
prev.next=null;
nodes.addAll(nextNodes);
}
return root;
}
更优
public Node connect(Node root) {
if (root == null)
return root;
//cur我们可以把它看做是每一层的链表
Node cur = root;
while (cur != null) {
//遍历当前层的时候,为了方便操作在下一
//层前面添加一个哑结点(注意这里是访问
//当前层的节点,然后把下一层的节点串起来)
Node dummy = new Node(0);
//pre表示访下一层节点的前一个节点
Node pre = dummy;
//然后开始遍历当前层的链表
while (cur != null) {
if (cur.left != null) {
//如果当前节点的左子节点不为空,就让pre节点
//的next指向他,也就是把它串起来
pre.next = cur.left;
//然后再更新pre
pre = pre.next;
}
//同理参照左子树
if (cur.right != null) {
pre.next = cur.right;
pre = pre.next;
}
//继续访问这一行的下一个节点
cur = cur.next;
}
//把下一层串联成一个链表之后,让他赋值给cur,
//后续继续循环,直到cur为空为止
cur = dummy.next;
}
return root;
}
118. Pascal’s Triangle
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> res=new ArrayList<>();
res.add(List.of(1));
if(numRows==1){
return res;
}
for (int i=2;i<=numRows;i++){
ArrayList<Integer> curr=new ArrayList<>();
curr.add(1);
for (int j=0;j<i-2;j++){
curr.add(res.get(i-2).get(j)+res.get(i-2).get(j+1));
}
curr.add(1);
res.add(curr);
}
return res;
}
119. Pascal’s Triangle II
public List<Integer> getRow(int rowIndex) {
List<Integer> res=new ArrayList<>();
res.add(1);
if(rowIndex==1){
res.add(1);
return res;
}
for (int i=2;i<=rowIndex+1;i++){
ArrayList<Integer> curr=new ArrayList<>();
curr.add(1);
for (int j=0;j<i-2;j++){
curr.add(res.get(j)+res.get(j+1));
}
curr.add(1);
res=curr;
}
return res;
}
120. Triangle (Solved)
public int minimumTotal(List<List<Integer>> triangle) {
if (triangle.size()==1){
return triangle.get(0).get(0);
}
int[] dp= new int[triangle.get(triangle.size()-1).size()];
for (int i=0;i<dp.length;i++){
dp[i]=triangle.get(triangle.size()-1).get(i);
}
for (int i=triangle.size()-2;i>=0;i--){
for (int j=0;j<triangle.get(i).size();j++){
dp[j]=Math.min(dp[j],dp[j+1])+triangle.get(i).get(j);
}
}
return dp[0];
}