leetCode刷题记录二

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Viscu/article/details/81906707
1、gas-station

There are N gas stations along a circular route, where the amount of gas at station i isgas[i].
You have a car with an unlimited gas tank and it costscost[i]of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.
Return the starting gas station’s index if you can travel around the circuit once, otherwise return -1.
Note:
The solution is guaranteed to be unique.
法一:预处理gas[i]-cost[i],排序,每次取最大的剩余汽油。
汽油剩余越多当前越好走接下来的路。
法二:先选定一个开始位置,如果我们往下走,若油不够的话,那我们边把开始位置往前挪一个位置。
例如6->0->1 的时候汽油不够那么就变成,5->6->0->1 以此类推。

public class _47 {
    class o{
        int ex;
        int index;
        public o(int ex, int index) {
            this.ex = ex;
            this.index = index;
        }
    }

    public int canCompleteCircuit(int[] gas, int[] cost) {
        int n=gas.length;
        List<o> queue=new ArrayList<o>();
        int[] ex=new int[n];
        for (int i = 0; i < n; i++) {
            ex[i]=gas[i]-cost[i];
            queue.add(new o(ex[i],i));
        }
        Collections.sort( queue, new Comparator<o>() {
            @Override
            public int compare(o o, o t1) {
                if(t1.ex>o.ex){
                    return 1;
                }else{
                    return -1;
                }
            }
        } );
        for (int j = 0; j < queue.size(); j++) {
            o cur=queue.get(j);
            int r=cur.ex;
            int i=(cur.index+1)%n;
            if(r<0){
                return -1;
            }
            while (i!=cur.index){
                r+=ex[i];
                if(r<0){
                    break;
                }
                i=(i+1)%n;
            }
            if(r>=0){
                return cur.index;
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        int[] gas={5};
        int[] cost={4};
        System.out.println(new _47().canCompleteCircuit(gas,cost));
    }
}
法二:
public int canCompleteCircuit(int[] gas, int[] cost) {
        int st=gas.length-1;
        int sum=gas[st]-cost[st];
        int ed=0;
        while (ed<st){
            if(sum>=0){
                sum+=gas[ed]-cost[ed++];
            }else{
                sum+=gas[--st]-cost[st];
            }
        }
        return sum>=0?st:-1;
    }
2.valid-palindrome

Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.
For example,
“A man, a plan, a canal: Panama”is a palindrome.
“race a car”is not a palindrome.
Note:
Have you consider that the string might be empty? This is a good question to ask during an interview.
For the purpose of this problem, we define empty string as valid palindrome.
递归爆栈,只能用迭代。
考虑一下情况,st是字符,ed不是字符,则–ed.
st不是字符,ed是字符,则++st,
st,ed都不是字符,++st,–ed.
st,ed都是字符且相等,++st,ed,否则返回false。

class _50{
    public boolean isPalindrome(String s) {
        int st=0;
        int ed=s.length()-1;
        while (ed>st){
            char stChar=s.charAt(st);
            char edChar=s.charAt(ed);
            if(stChar==edChar||(!Character.isLetterOrDigit(edChar)&&!Character.isLetterOrDigit(stChar))){
                --ed;
                ++st;
            }else if(!Character.isLetterOrDigit(stChar)&&Character.isLetterOrDigit(edChar)){
                ++st;
            }else if(!Character.isLetterOrDigit(edChar)&&Character.isLetterOrDigit(stChar)){
                --ed;
            }else{
                return false;
            }
        }
        return true;
    }
    public static void main(String[] args) {
        String s=".,";
        System.out.println(new _50().isPalindrome(s));
    }
}
3.pascals-triangle

Given numRows, generate the first numRows of Pascal’s triangle.
For example, given numRows = 5,
Return
[
[1],
[1,1],
[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]
可以用二维数组模拟在添加,也可以直接用容器添加。

public class _51 {
    public ArrayList<ArrayList<Integer>> generate(int numRows) {
        if(numRows==0){
            return new ArrayList<ArrayList<Integer>>();
        }
        ArrayList<ArrayList<Integer>> res=new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> fir=new ArrayList<Integer>();
        fir.add(1);
        res.add(fir);
        for (int i = 2; i <= numRows; i++) {
            ArrayList<Integer> k=new ArrayList<Integer>();
            k.add(1);
            for (int j = 2; j <= i-1; j++) {
                k.add(res.get(i-2).get(j-2)+res.get(i-2).get(j-1));
            }
            k.add(1);
            res.add(k);
        }
        return res;
    }
    public static void main(String[] args) {
        System.out.println(new _51().generate(0));
    }
}

4.pascals-triangle-ii

Given an index k, return the k th row of the Pascal’s triangle.
For example, given k = 3,
Return[1,3,3,1].
Note:
Could you optimize your algorithm to use only O(k) extra space?
O(k)做法。
杨辉三角,第n行第m个数的值为C(m-1,n-1).
用double来进行乘除运算,会出现精度问题,
所以我们要进行精度控制,若大于等于eps我们则向上取整,若小与我们则向下取整即可。
这道题用long可以直接过,emmm,不需要考虑精度。

一.
public ArrayList<Integer> getRow(int rowIndex) {
        double eps=1e-6;
        ArrayList<Integer> res=new ArrayList<Integer>();
        if(rowIndex==0){
            res.add(1);
            return res;
        }
        rowIndex+=1;
        res.add(1);
        double up;
        double down;
        double re=1;
        for (int i = 2; i <= rowIndex-1; i++) {
            down=i-1;
            up=rowIndex-i+1;
            re=re/down*up;
            if(re-(int)re<eps){ 
                re=Math.floor(re);
            }else{
                re=Math.ceil(re);
            }
            res.add((int) re);
        }
        res.add(1);
        return res;
    }
二:    
public ArrayList<Integer> getRow(int rowIndex) {
        ArrayList<Integer> res=new ArrayList<Integer>();
        if(rowIndex==0){
            res.add(1);
            return res;
        }
        rowIndex+=1;
        res.add(1);
        long up;
        long down;
        long re=1;
        for (int i = 2; i <= rowIndex-1; i++) {
            down=i-1;
            up=rowIndex-i+1;
            re=re*up/down;
            res.add((int) re);
        }
        res.add(1);
        return res;
    }
5.binary-tree-maximum-path-sum

Given a binary tree, find the maximum path sum.
The path may start and end at any node in the tree.
For example:
Given the below binary tree,
1
/ \
2 3
Return6.

public class _53 {
    static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int x) { val = x; }
    }
    int max;
    public int maxPathSum(TreeNode root) {
        max=Integer.MIN_VALUE;
        dfs(root);
        return max;
    }
    private int dfs(TreeNode root){
        if(root==null){
            return 0;
        }
        int l=Math.max(dfs(root.left),0); //root的左边谁最大
        int r=Math.max(dfs(root.right),0); //root的左边谁最大
        max=Math.max(max,root.val+l+r); //左右加上还有根
        return Math.max(l,r)+root.val; //返回左右子树哪个的值比较大。
    }
    public static void main(String[] args) {
        TreeNode treeNode=new TreeNode(-2);
        System.out.println(new _53().maxPathSum(treeNode));
    }
}
6.sum-root-to-leaf-numbers

Given a binary tree containing digits from0-9only, each root-to-leaf path could represent a number.
An example is the root-to-leaf path1->2->3which represents the number123.
Find the total sum of all root-to-leaf numbers.
For example,
1
/ \
2 3
The root-to-leaf path1->2represents the number12.
The root-to-leaf path1->3represents the number13.
Return the sum = 12 + 13 =25.
左右子树遍历一遍即可。

public class _54 {
    int sum;
    public int sumNumbers(TreeNode root) {
        if(root==null){
            return 0;
        }
        sum=0;
        dfs(root,0);
        return sum;
    }
    private void dfs(TreeNode root,int res){
        res=res*10+root.val;
        if(root.left==null&&root.right==null){
            sum+=res;
            return;
        }
        if(root.left!=null){
            dfs(root.left,res);
        }
        if(root.right!=null){
            dfs(root.right,res);
        }
    }
    public static void main(String[] args) {
        TreeNode treeNode=new TreeNode(1);
        treeNode.left=new TreeNode(2);
        treeNode.right=new TreeNode(3);
        System.out.println(new _54().sumNumbers(treeNode));
    }
}
7.populating-next-right-pointers-in-each-node

Given a binary tree

struct TreeLinkNode {
  TreeLinkNode *left;
  TreeLinkNode *right;
  TreeLinkNode *next;
}

Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set toNULL.
Initially, all next pointers are set toNULL.
Note:
You may only use constant extra space.
You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).

For example,
Given the following perfect binary tree,

     1
   /  \
  2    3
 / \  / \
4  5  6  7

After calling your function, the tree should look like:

     1 -> NULL
   /  \
  2 -> 3 -> NULL
 / \  / \
4->5->6->7 -> NULL
public class Solution {
    public void connect(TreeLinkNode root) {
        if(root==null){
            return;
        }
        if(root.left!=null&&root.right!=null){
            root.left.next=root.right;
        }
        if(root.right!=null&&root.next!=null){
            root.right.next=root.next.left;
        }
        connect(root.left);
        connect(root.right);
    }
}
7.populating-next-right-pointers-in-each-node-ii

Follow up for problem “Populating Next Right Pointers in Each Node”.
What if the given tree could be any binary tree? Would your previous solution still work?
Note:
You may only use constant extra space.
For example,
Given the following binary tree,

     1
   /  \
  2    3
 / \    \
4   5    7

After calling your function, the tree should look like:

     1 -> NULL
   /  \
  2 -> 3 -> NULL
 / \    \
4-> 5 -> 7 -> NULL

BFS即可。上一题也可以这样子做。

public void connect(TreeLinkNode root) {
        if(root==null){
            return;
        }
        Queue<TreeLinkNode> queue=new LinkedList<TreeLinkNode>();
        queue.add(root);
        while (!queue.isEmpty()){
            int size=queue.size();
            for(int i=1;i<=size;++i){
                TreeLinkNode pre=queue.poll();
                if(i!=size) {
                    pre.next = queue.peek();
                }
                if(pre.left!=null){
                    queue.add(pre.left);
                }
                if(pre.right!=null){
                    queue.add(pre.right);
                }
            }
        }
    }
8.balanced-binary-tree

Given a binary tree, determine if it is height-balanced.
For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
判断一颗二叉树是否高度平衡,首先呢,我们需要求节点的左右孩子的最大的深度,若深度差大于1则返回false。
需要对每个节点的左右孩子都判断一次深度差。

public class _57 {
    public boolean isBalanced(TreeNode root) { //对每个节点的左右孩子节点进行判断
        if (root==null){
            return true;
        }
        if(Math.abs(MaxDeepth(root.left)-MaxDeepth(root.right))>1){
            return false;
        }
        return isBalanced(root.left)&&isBalanced(root.right);
    }
    public int MaxDeepth(TreeNode treeNode){ //求最大深度
        if(treeNode==null){
            return 0;
        }
        int l=MaxDeepth(treeNode.left);
        int r=MaxDeepth(treeNode.right);
        return 1+Math.max(l,r);
    }
}
9.path-sum

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.
For example:
Given the below binary tree andsum = 22,

          5
         / \
        4   8
       /   / \
      11  13  4
     /  \      \
    7    2      1

return true, as there exist a root-to-leaf path5->4->11->2which sum is 22.
dfs即可。

public class _58 {
    static boolean flag;
    public boolean hasPathSum(TreeNode root, int sum) {
        if(root==null){
            return false;
        }
        flag=false;
        dfs(root,root.val,sum);
        return flag;
    }
    private void dfs(TreeNode treeNode,int res,int sum){
        if(flag){ 
            return;
        }
        if(res==sum&&treeNode.left==null&&treeNode.right==null){ //注意 {-2 # -3} -2 false
            flag=true;
            return;
        }
        if(treeNode.left!=null){
            dfs(treeNode.left,res+treeNode.left.val,sum);
        }
        if(treeNode.right!=null){
            dfs(treeNode.right,res+treeNode.right.val,sum);
        }
    }
}

10.path-sum-ii
Given a binary tree and a sum, find all root-to-leaf paths where each path’s sum equals the given sum.
For example:
Given the below binary tree andsum = 22,

          5
         / \
        4   8
       /   / \
      11  13  4
     /  \    / \
    7    2  5   1

return
[
[5,4,11,2],
[5,8,4,5]
]
和上一题一样,加个容器存一下值即可。

class _59{
    static boolean flag;
    ArrayList<ArrayList<Integer>> ans;
    public ArrayList<ArrayList<Integer>> pathSum(TreeNode root, int sum) {
        if(root==null){
            return new ArrayList<ArrayList<Integer>>();
        }
        flag=false;
        ans=new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> pos=new ArrayList<Integer>();
        pos.add(root.val);
        dfs(root,root.val,sum,pos);
        if(!flag){
            return new ArrayList<ArrayList<Integer>>();
        }
        return ans;
    }
    private void dfs(TreeNode treeNode,int res,int sum,ArrayList<Integer> pos){
        if(res==sum&&treeNode.left==null&&treeNode.right==null){
           ans.add(new ArrayList<Integer>(pos));
           flag=true;
        }
        if(treeNode.left!=null){
            pos.add(treeNode.left.val);
            dfs(treeNode.left,res+treeNode.left.val,sum,pos);
            pos.remove(pos.size()-1);
        }
        if(treeNode.right!=null){
            pos.add(treeNode.right.val);
            dfs(treeNode.right,res+treeNode.right.val,sum,pos);
            pos.remove(pos.size()-1);
        }
    }
}
11.same-tree

Given two binary trees, write a function to check if they are equal or not.
Two binary trees are considered equal if they are structurally identical and the nodes have the same value.
搜索一遍即可。

public class _60 {
    boolean flag;
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if(p==null||q==null){ 
            return p==q;
        }
        if(p.val!=q.val){
            return false;
        }
        return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
    }
}
12.symmetric-tree

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
For example, this binary tree is symmetric:

   1
   / \
  2   2
 / \ / \
3  4 4  3

But the following is not:

   1
   / \
  2   2
   \   \
   3    3

Note:
Bonus points if you could solve it both recursively and iteratively.
confused what”{1,#,2,3}”means? > read more on how binary tree is serialized on OJ.
利用对称性,进行dfs即可。
dfs(l.left,r.right)&&dfs(l.right,r.left)

public boolean isSymmetric(TreeNode root) {
        return dfs(root,root);
    }
    private boolean dfs(TreeNode l,TreeNode r){
        if(l==null||r==null){
            return l==r;
        }
        return l.val==r.val&&dfs(l.left,r.right)&&dfs(l.right,r.left);
    }
13.maximum-depth-of-binary-tree

求最大深度,没什么好说的,dfs左右孩子即可。

class _63{
    public int maxDepth(TreeNode root) {
        if(root==null){
            return 0;
        }
        return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
    }
}
14.binary-tree-level-order-traversal-ii

Given a binary tree, return the bottom-up level order traversal of its nodes’ values. (ie, from left to right, level by level from leaf to root).
For example:
Given binary tree{3,9,20,#,#,15,7},

    3
   / \
  9  20
    /  \
   15   7

return its bottom-up level order traversal as:
[
[15,7]
[9,20],
[3],
]
confused what”{1,#,2,3}”means? > read more on how binary tree is serialized on OJ.
BFS即可。

class _64{
    public ArrayList<ArrayList<Integer>> levelOrderBottom(TreeNode root) {
        if(root==null){
            return new ArrayList<ArrayList<Integer>>();
        }
        ArrayList<ArrayList<Integer>> ans=new ArrayList<ArrayList<Integer>>();
        Queue<TreeNode> queue=new LinkedList<TreeNode>();
        queue.add(root);
        while (!queue.isEmpty()){
            int size=queue.size();
            ArrayList<Integer> dummy=new ArrayList<Integer>();
            for (int i = 0; i < size; i++) {
                TreeNode cur=queue.poll();
                dummy.add(cur.val);
                if(cur.left!=null){
                    queue.add(cur.left);
                }
                if(cur.right!=null){
                    queue.add(cur.right);
                }
            }
            ans.add(dummy);
        }
        Collections.reverse(ans);
        return ans;
    }
}
15.construct-binary-tree-from-preorder-and-inorder-traversal

Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
深搜,没啥好说的,不懂找参考。

class _65{
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return build(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
    }
    public TreeNode build(int[] pre,int pS,int pE,int[] in,int iS,int iE){
        if(pS>pE||iS>iE){
            return null;
        }
        TreeNode root=new TreeNode(pre[pS]);
        for (int i = 0; i < in.length; i++) {
            if(in[i]==pre[pS]){
                root.left=build(pre,pS+1,pS+i-iS,in,iS,i-1);
                root.right=build(pre,pS+1+i-iS,pE,in,i+1,iE);
            }
        }
        return root;
    }
}

16.construct-binary-tree-from-inorder-and-postorder-traversal

Given inorder and postorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
中序遍历和后序遍历确定二叉树,和前序遍历,中序遍历确定二叉树代码差不多,
前者根是从后面开始,后者是根从前面开始。

class _66{
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        return build(postorder,0,postorder.length-1,inorder,0,inorder.length-1);
    }
    private TreeNode build(int[] post,int pS,int pE,int[] in,int iS,int iE){
        if(pS>pE||iS>iE){
            return null;
        }
        TreeNode root=new TreeNode(post[pE]);
        for (int i = 0; i < in.length; i++) {
            if(in[i]==post[pE]){
                root.left=build(post,pS,pS-1+i-iS,in,iS,i-1);
                root.right=build(post,pS+i-iS,pE-1,in,i+1,iE);
            }
        }
        return root;
    }
}
17.binary-tree-level-order-traversal

与之前的题目差不多。

Given a binary tree, return the level order traversal of its nodes’ values. (ie, from left to right, level by level).
For example:
Given binary tree{3,9,20,#,#,15,7},

    3
   / \
  9  20
    /  \
   15   7

return its level order traversal as:

[
[3],
[9,20],
[15,7]
]
confused what”{1,#,2,3}”means? > read more on how binary tree is serialized on OJ.

18.binary-tree-zigzag-level-order-traversal

Given a binary tree, return the zigzag level order traversal of its nodes’ values. (ie, from left to right, then right to left for the next level and alternate between).
For example:
Given binary tree{3,9,20,#,#,15,7},

    3
   / \
  9  20
    /  \
   15   7

return its zigzag level order traversal as:

[
[3],
[20,9],
[15,7]
]

confused what”{1,#,2,3}”means? > read more on how binary tree is serialized on OJ.
emmmm…一样的题目,把i%2==0的层使用 Collections.reverse(ans.get(i));即可。

public class Solution {
    public ArrayList<ArrayList<Integer>> zigzagLevelOrder(TreeNode root) {
        if(root==null){
            return new ArrayList<ArrayList<Integer>>();
        }
        ArrayList<ArrayList<Integer>> ans=new ArrayList<ArrayList<Integer>>();
        Queue<TreeNode> queue=new LinkedList<TreeNode>();
        queue.add(root);
        while (!queue.isEmpty()){
            int size=queue.size();
            ArrayList<Integer> dummy=new ArrayList<Integer>();
            for (int i = 0; i < size; i++) {
                TreeNode cur=queue.poll();
                dummy.add(cur.val);
                if(cur.left!=null){
                    queue.add(cur.left);
                }
                if(cur.right!=null){
                    queue.add(cur.right);
                }
            }
            ans.add(dummy);
        }
        for (int i = 0; i < ans.size(); i++) {
            if(i%2!=0){
                Collections.reverse(ans.get(i));
            }
        }
        return ans;
    }
}
15.validate-binary-search-tree

Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
The left subtree of a node contains only nodes with keys less than the node’s key.
The right subtree of a node contains only nodes with keys greater than the node’s key.
Both the left and right subtrees must also be binary search trees.
confused what”{1,#,2,3}”means? > read more on how binary tree is serialized on OJ.
中序遍历判断即可,pre为当前节点的前驱节点,若pre.val>=cur.val的话,那么它不是一颗二叉搜索树,
BST中序遍历之后的序列是呈递增的。

public class _67 {
    static TreeNode pre;
    public boolean isValidBST(TreeNode root) {
        pre=null;
        return dfs(root);
    }
    private boolean dfs(TreeNode root){
        if(root==null){
            return true;
        }
        if(!dfs(root.left)){
            return false;
        }
        if(pre!=null&&pre.val>=root.val){
            return false;
        }
        pre=root;
        return dfs(root.right);
    }
    public static void main(String[] args) {
        TreeNode node=new TreeNode(0);
        node.left=new TreeNode( -1);
        System.out.println(new _67().isValidBST(node));
    }
}
16.unique-binary-search-trees

Given n, how many structurally unique BST’s (binary search trees) that store values 1…n?
For example,
Given n = 3, there are a total of 5 unique BST’s.

  1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

思路,我们先确定根节点,那么,左右子树的个数就可以随意分配。
例如4,
1.左边0个节点,右边3个;
2.左边1个节点,右边2个;
3.左边2个节点,右边1个;
所有情况加起来。
转移方程就是
dp[i]+=dp[j]*dp[i-j-1]

public class _68 {
    public int numTrees(int n) {
        int[] dp=new int[n+1];
        dp[0]=1;
        dp[1]=1;
        for (int i = 2; i <= n; i++) {
            for (int j = 0; j < i; j++) {
                dp[i]+=dp[j]*dp[i-j-1];
            }
        }
        return dp[n];
    }

    public static void main(String[] args) {
        System.out.println(new _68().numTrees(2));
    }
}

猜你喜欢

转载自blog.csdn.net/Viscu/article/details/81906707