• LeetCode---Depth-first && Breadth-first


    417. Pacific Atlantic Water Flow
    思路:构造两个二维数组分别存储大西洋和太平洋的结果,先初始化边界,然后从边界出发,深度优先遍历,标记满足条件的所有节点
    
    static int[] dx = new int[]{-1,0,0,1};
    static int[] dy = new int[]{0,1,-1,0}; 
    public List<int[]> pacificAtlantic(int[][] matrix) {
        List<int[]> res = new ArrayList<int[]>();
        if(matrix == null || matrix.length == 0) return res;
        int m = matrix.length;
        int n = matrix[0].length;
        boolean[][] p = new boolean[m][n];
        boolean[][] a = new boolean[m][n];
        
        //初始化两条边
        for(int j = 0; j < n; j++){
            p[0][j] = true;
            a[m - 1][j] = true;
        }
        
        for(int i = 0; i < m; i++){
            p[i][0] = true;
            a[i][n - 1] = true;
        }
        
        //判断该点能不能流入两个海
        for(int j = 0; j < n; j++){
            dfs(matrix,p,0,j);
            dfs(matrix,a,m - 1,j);
        }
        
        for(int i = 0; i < m; i++){
            dfs(matrix,p,i,0);
            dfs(matrix,a,i,n - 1);
        }
        
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(p[i][j] && a[i][j]){
                    res.add(new int[]{i,j});
                }
            }
        }
        return res;
    }
    
    public void dfs(int[][] matrix,boolean[][] dp,int row,int col){
        dp[row][col] = true;
        int m = matrix.length;
        int n = matrix[0].length;
        for(int i = 0; i < 4; i++){
            int p = row + dx[i];
            int q = col + dy[i];
            if(p < m && p >= 0 && q < n && q >= 0){
                if(matrix[row][col] <= matrix[p][q] && dp[p][q] == false) dfs(matrix,dp,p,q);
            }
        }
    }
    
    473. Matchsticks to Square
    思路:首先和不是4的整数倍,return false,然后将数组逆序排序,这样能更快的搜索到结果,然后深度优先遍历最后能将数组遍历完并且每条边都能等于target即可
    
    public boolean makesquare(int[] nums) {
        if(nums == null || nums.length < 4) return false;
        int sum = 0;
        for(int num : nums){
            sum += num;
        }
        if(sum % 4 != 0) return false;
        //将数组逆序排序以后能更快的搜索到结果
        Arrays.sort(nums);
        reverse(nums);
        return dfs(nums,new int[4],0,sum / 4);
    }
    
    public boolean dfs(int[] nums,int[] sum,int idx,int target){
        if(idx == nums.length && sum[0] == target && sum[1] == target && sum[2] == target){
            return true;
        }
        
        for(int i = 0; i < 4; i++){
            if(sum[i] + nums[idx] > target) continue;
            sum[i] += nums[idx];
            if(dfs(nums,sum,idx + 1,target)) return true;
            sum[i] -= nums[idx];
        }
        return false;
    }
    
    public void reverse(int[] nums){
        int i = 0;
        int j = nums.length - 1;
        while(i < j){
            int temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
            i++;
            j--;
        }
    }
    
    总结
    207. Course Schedule:利用拓扑排序,不断取出入度为0的节点,判断最终计数器的值和节点个数是否一致,等价于判断有没有环
    133. Clone Graph:利用map存下node.label和node对,方便查找
    
    训练
    332. Reconstruct Itinerary:利用map将节点和与之关联的节点保存起来,并利用优先队列进行排序,最后输出结果的时候,优先将堵塞的路径节点添加到结果前面
    210. Course Schedule II:思路同207,但是要考虑没有先决条件的情况
    200. Number of Islands:深度优先遍历,依次将每个岛中的1都变为0,同时计数
    472. Concatenated Words:首先根据字符串长度排序,将短的一依次存入dict用作备选,之后动态规划依次判断后面的长字符串能否用短字符串拼接起来
    329. Longest Increasing Path in a Matrix:深度优先遍历,依次找到递增的序列,注意利用之前的结果避免重复搜索
    279. Perfect Squares:动态规划,res[n] = Min{ res[n - i * i] + 1 },  n - i * i >= 0 && i >= 1
    310. Minimum Height Trees:首先将图的结构用map保存下来,然后取出叶子节点,依次将叶子节点和分支去除,得到新的叶子节点,若最后剩下的节点数<=2则作为结果返回
    
    提示
    1、将结果从后往前添加的经验-->332题
    2、在二维数组中深度优先遍历的经验 构造两个数组保存四个方向-->417 200 329题
    3、拓扑排序的算法-->207 210题
  • 相关阅读:
    第一阶段冲刺10天 第六天
    第一阶段冲刺10天 第五天
    第一阶段冲刺10天 第四天
    第一阶段冲刺10天 第三天
    第一阶段冲刺10天 第二天
    第一阶段冲刺10天 第一天
    典型用户分析
    第二次小组冲刺训练
    寻找水王代码(找多个字母中出现最多次数的字母)
    冲刺周期第二天
  • 原文地址:https://www.cnblogs.com/LeonNew/p/6288993.html
Copyright © 2020-2023  润新知