算法刷题记录(LeetCode 91-120)

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];
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值