zoukankan      html  css  js  c++  java
  • leetcode 684.354,133,207,121,63,64,jz46,120,357

    684 冗余连接

       不得不说并查集真的是一种很巧妙的思维了。。。

    int[] visit;
    
        public int[] findRedundantConnection(int[][] edges) {
            visit = new int[edges.length+1];
            for (int i = 0; i < visit.length; i++) {
                visit[i] = i;
            }
            for (int i = 0; i < edges.length; i++) {
                if (!connectd(edges[i][0],edges[i][1])){
                    union(edges[i][0],edges[i][1]);
                }else {
                    return edges[i];
                }
            }
    
            return null;
        }
        public void union(int p,int q){
            int s = visit[p],t = visit[q];
            if (s != t){
                for (int i = 0; i < visit.length; i++) {
                    if (visit[i] == s){
                        visit[i] = t;
                    }
                }
            }
        }
        public boolean connectd(int p,int q){
            return visit[p] == visit[q];
        }

       然后由于union的复杂度是On,这儿还可以进行优化,quik union。具体的就是相当的亲戚只保留一个根节点 即p = visit[p],其他的都指向自己的父节点即可

      public void union(int p,int q){
            int proot = find(p);
            int qroot = find(q);
            if (proot == qroot){
                return;
            }
            visit[proot] = qroot;
        }
    
        public int find(int p){
            while (p != visit[p]){
                p = visit[p];
            }
            return p;
        }
        public boolean connectd(int p,int q){
            return find(p) == find(q);
        }

      然后这儿如果整个列表都是亲戚,而且顺序极端的情况下会形成一个链表。所以还能继续优化  具体的优化可以查看这边博客 传送门→https://www.cnblogs.com/ggnbnb/p/12586205.html

    354 俄罗斯套娃的问题   记住相等是不行的

       其实就是个最长递增子序列的问题,这题还有个贪心+二分的解法。。有兴趣的可以去了解下

        public int maxEnvelopes(int[][] envelopes) {
     Arrays.sort(envelopes, new Comparator<int[]>() {
                @Override
                public int compare(int[] o1, int[] o2) {
                    return o1[1]-o2[1];
                }
            });
           int[] dp = new int[envelopes.length];
           dp[0] = 1;
            int max = 1;
            for (int i = 1; i < envelopes.length; i++) {
                dp[i] = 1;
                int[] cu = envelopes[i];
                for (int j = 0; j < i; j++) {
                    if (cu[0]>envelopes[j][0] && cu[1]>envelopes[j][1]){
                        dp[i] = Math.max(dp[i],dp[j]+1);
                    }
    
                }
                max = Math.max(max,dp[i]);
    
            }
            return max;
        }

       

    133 克隆图

       这题我做的和官解一样。。但不知道为何打败人数很少。。

    Map<Integer,Node> nodeMap;
    
        public Node cloneGraph(Node node) {
            if (node == null){
                return null;
            }
            nodeMap = new HashMap<>();
            return dfs(node);
        }
    
        public Node dfs(Node node){
            Node cu = new Node(node.val);
            nodeMap.put(node.val,cu);
            List<Node> cns = cu.neighbors;
            List<Node> ns =  node.neighbors;
            for (Node n : ns) {
                if (nodeMap.containsKey(n.val)){
                    cns.add(nodeMap.get(n.val));
                }else {
                    cns.add(dfs(n));
                }
    
            }
            return cu;
    
        }
    
    
         static class Node {
            public int val;
            public List<Node> neighbors;
            public Node() {
                val = 0;
                neighbors = new ArrayList<Node>();
            }
            public Node(int _val) {
                val = _val;
                neighbors = new ArrayList<Node>();
            }
            public Node(int _val, ArrayList<Node> _neighbors) {
                val = _val;
                neighbors = _neighbors;
            }
        }

    207 这是之前做过的一个题,当时用的dfs,现在才知道还可以用拓扑排序

    public static boolean canFinish(int numCourses, int[][] prerequisites) {
            Map<Integer, List<Integer>> map = new HashMap<>();
            int[] arr = new int[numCourses];
            for (int[] ar : prerequisites) {
                int x1 =ar[0],x2 = ar[1];
                arr[x2]+=1;
                List<Integer> forws = map.get(x1);
                if (forws == null){
                    forws = new ArrayList<>();
                    map.put(x1,forws);
                }
                forws.add(ar[1]);
    
    
            }
            //计算入度
            while (!map.isEmpty()){
                int size = map.size();
                Set<Integer> set = map.keySet();
                Iterator<Integer> iterator = set.iterator();
                boolean circle = true;
                while (iterator.hasNext()){
                    Integer value = iterator.next();
                    if (arr[value] == 0){
                        circle = false;
                        List<Integer> childs = map.get(value);
                        for (Integer child : childs) {
                            if (arr[child]>0){
                                arr[child]--;
                            }
                        }
                        iterator.remove();
                    }
                }
                if (circle){
                    return false;
                }
    
            }
            return true;
    
    
        }

    53 最大子序和

        public static int maxSubArray(int[] nums) {
            if (nums.length <1){
                return 0;
            }
    
            int pre = nums[0];
            int max = pre;
            for (int i = 1; i < nums.length; i++) {
                pre = Math.max(nums[i],pre+nums[i]);
                max = Math.max(pre,max);
            }
            return max;
        }

    70  爬楼梯   一次一步 或者两步  N步一共有多少种方法

        public static int climbStairs(int n) {
            if (n <= 3){
                return n;
            }
            int[] dp = new int[n+1];
            dp[1] = 1;dp[2] = 2;dp[3] = 3;
            for (int i = 4; i <=n ; i++) {
                dp[i] = dp[i-2]+dp[i-1];
            }
            return dp[n];
    
        }

    121 买卖股票的最佳时机

        public static int maxProfit(int[] prices) {
            int k = prices[0];
            int max = 0;
            for (int i = 1; i < prices.length; i++) {
                int c = prices[i];
                if (c > k){
                    max = Math.max(max, c- k);
                }else {
                    k = c;
                }
    
            }
            return max;
        }

    63 不同路径

    public static int uniquePathsWithObstacles(int[][] obstacleGrid) {
            if (obstacleGrid[0][0] == 1){
                return 0;
            }
            int m = obstacleGrid.length,n = obstacleGrid[0].length;
            int[][] dp = new int[m][n];
            boolean t1 = true,t2 = true;
            for (int i = 0; i < m; i++) {
                if (obstacleGrid[i][0] == 1){
                    t1 = false;
                }
                if (t1){
                    dp[i][0] = 1  ;
                }
                if (i == 0){
                    for (int j = 1; j < n; j++) {
                        if (obstacleGrid[0][j] == 1){
                            t2 = false;
                        }
                        if (t2){
                            dp[0][j] = 1;
                        }
    
                    }
                }
    
            }
            for (int i = 1; i < m; i++) {
                for (int j = 1; j < n; j++) {
                    if (obstacleGrid[i][j] != 1){
                        dp[i][j] = dp[i-1][j]+dp[i][j-1];
                    }
                }
            }
            return dp[m-1][n-1];
            
        }

    64 最小路径和

        public static int minPathSum(int[][] grid) {
            int m = grid.length,n = grid[0].length;
            int[][] dp = new int[m][n];
            boolean t1 = true,t2 = true;
            dp[0][0] = grid[0][0];
            for (int i = 1; i < m; i++) {
                dp[i][0] = dp[i-1][0]+grid[i][0];
            }
            for (int i = 1; i < n; i++) {
                dp[0][i] = dp[0][i-1]+grid[0][i];
            }
            for (int i = 1; i < m; i++) {
                for (int j = 1; j < n; j++) {
                    dp[i][j] = Math.min(dp[i-1][j],dp[i][j-1])+grid[i][j];
                }
            }
            return dp[m-1][n-1];
            
        }

    数字翻译成字符串

       思路是如果当前字符和前一个字符可以组成一个有效数字,那么出现的情况就等于前一个加上前前一个字符的情况。否则就等于前一个字符的情况

        public static int translateNum(int num) {
            String value = String.valueOf(num);
            int[] dp = new int[value.length()];
    
            dp[0] = 1;
            if (value.length()<=1){
                return dp[0];
            }
            int pre = value.charAt(0)-48;
            dp[1] = pre*10+value.charAt(1)-48 >25?1:2;
            if (value.length()<=2){
                return dp[1];
            }
            pre = dp[1];
            for (int i = 2; i < value.length(); i++) {
                if (pre == 0 || pre*10+value.charAt(i)-48 > 25){
                    dp[i] = dp[i-1];
                }else {
                    dp[i] = dp[i-1]+dp[i-2];
                }
                pre = value.charAt(i)-48;
            }
            return dp[value.length()-1];
        }

    120 三角形的最小路径和

    public static int minimumTotal1(List<List<Integer>> triangle) {
            if (triangle.size() == 1){
                return triangle.get(0).get(0);
            }
            int[][] dp = new int[triangle.size()][triangle.size()];
            dp[0][0] = triangle.get(0).get(0);
            int min = Integer.MAX_VALUE;
            for (int i = 1; i < triangle.size(); i++) {
                List<Integer> integers = triangle.get(i);
                for (int j = 0; j < integers.size(); j++) {
                    if (j == 0){
                        dp[i][j] = dp[i-1][j] +integers.get(j);
                    }else if (j == integers.size()-1){
                        dp[i][j] = dp[i-1][j-1] +integers.get(j);
                    }
                    else {
                        dp[i][j] = Math.min(dp[i-1][j],dp[i-1][j-1])+integers.get(j);
                    }
                    if (i == triangle.size()-1){
                        min = Math.min(min,dp[i][j]);
                    }
                }
            }
            return min;
        }

    357 计算各个位数不同的数的数字个数

       解析直接看如下,摘自题解,就是一个组合的知识吧

        public static int countNumbersWithUniqueDigits(int n) {
            int[] dp = new int[n+1];
            dp[0] = 0;
            if (n == 0 ){
                return dp[0];
            }
            dp[1] = 10;
            if (n == 1){
                return dp[1];
            }
            dp[2] = 91;
            if (n == 2){
                return dp[2];
            }
            int s = 81;
            for (int i = 3; i <= n; i++) {
                s *= 11-i;
                dp[i] = dp[i-1]+s;
            }
            return dp[n];
        }
  • 相关阅读:
    CH Dream(侠客行)
    EDS(特征)
    EDS(架构)
    通过红外线设备进行TCP/IP互连
    CH Dream(道路)
    北漂实习那些话【一】
    程序员,有时我们应该懂得
    迷茫的IT小小鸟
    《PHP求职宝典》PHP语言基础笔记
    Android中Activity启动模式详解
  • 原文地址:https://www.cnblogs.com/hetutu-5238/p/14482362.html
Copyright © 2011-2022 走看看