• leetcode 130,200,207,329,491,494,416,547,51


    130 被围绕的区域

        boolean[][] flag;
        char[][] bod;
        int deep,width;
        public  void solve(char[][] board) {
            if (board.length == 0){
                return;
            }
             deep = board.length;
             width = board[0].length;
            bod = board;
            flag = new boolean[deep][width];
    
            for (int i = 0; i < deep; i++) {
                for (int j = 0; j < width; j++) {
                    if ( (i == 0 || i == deep-1 || j == 0 || j == width-1) && (bod[i][j] == 'O')){
                        dfs(i,j);
                    }
                }
            }
    
            for (int i = 0; i < deep; i++) {
                for (int j = 0; j < width; j++) {
                    if (board[i][j] == 'O' && !flag[i][j]){
                        board[i][j] = 'X';
                    }
                }
            }
        }
    
        public void dfs(int x,int y){
            if (flag[x][y] == true){
                return;
            }
            flag[x][y] = true;
    
            if (x-1>0 && bod[x-1][y] == 'O'){
                dfs(x-1,y);
            }
            if (x+1<deep && bod[x+1][y] == 'O'){
                dfs(x+1,y);
            }
            if (y-1>0 && bod[x][y-1] == 'O'){
                dfs(x,y-1);
            }
            if (y+1<width && bod[x][y+1] == 'O'){
                dfs(x,y+1);
            }
    
    
    
        }
    
    }

    200 岛屿的数量  简单题重拳出击

       

      char[][] grid;
        int deep,width;
        public int numIslands(char[][] grids) {
            deep = grid.length;
            width = grid[0].length;
            this.grid = grids;
            int result = 0;
            for (int i = 0; i < deep; i++) {
                for (int j = 0; j < width; j++) {
                    if (grid[i][j] == '1'){
                        result++;
                        dfs(i,j);
                    }
                }
            }
            return result;
        }
    
        public void dfs(int x,int y){
            grid[x][y] = '0';
            if (x-1>0 && grid[x-1][y] == '1'){
                dfs(x-1,y);
            }
            if (x+1<deep && grid[x+1][y] == '1'){
                dfs(x+1,y);
            }
            if (y-1>0 && grid[x][y-1] == '1'){
                dfs(x,y-1);
            }
            if (y+1<width && grid[x][y+1] == '1'){
                dfs(x,y+1);
            }
        }

    207 课程表闭环

        Map<Integer, List<Integer>> map;
        Map<Integer,Boolean> flag;
        Set<Integer> set;
        public boolean canFinish(int numCourses, int[][] prerequisites) {
            map = new HashMap<>();
            flag = new HashMap<>();
            set = new HashSet<>();
            for (int[] prerequisite : prerequisites) {
                List<Integer> integers = map.get(prerequisite[0]);
                if (integers == null){
                    integers = new ArrayList<>();
                    map.put(prerequisite[0],integers);
                }
                integers.add(prerequisite[1]);
            }
            Set<Integer> integers = map.keySet();
            for (Integer integer : integers) {
                if (!dfs(integer)){
                    return false;
                }
                set.clear();
            }
    
            return true;
    
        }
    
        public boolean dfs(int num){
    
            Boolean current = flag.get(num);
            if (current != null){
                flag.put(num,current);
                return current;
            }
            if (set.contains(num)){
                flag.put(num,false);
                return false;
            }
            set.add(num);
            List<Integer> nexts = map.get(num);
            if (nexts == null || nexts.isEmpty()){
                flag.put(num,true);
                return true;
            }
            boolean dfs = true;
            for (Integer next : nexts) {
               // if (next)
                 dfs &= dfs(next);
            }
            flag.put(num,dfs);
            return dfs;
        }

    211 添加与搜索单词

     DicNode root;
        /** Initialize your data structure here. */
        public DFS5() {
            root = new DicNode('o');
        }
    
        public void addWord(String word) {
            char[] chars = word.toCharArray();
            DicNode tp = root;
            for (int i = 0; i < chars.length; i++) {
                char c = chars[i];
                DicNode son = tp.son.get(c);
                if (son == null){
                    son = new DicNode(c);
                    tp.son.put(c,son);
                }
                if (i == chars.length-1){
                    son.end = true;
                }
                tp = son;
            }
        }
    
        public boolean search(String word) {
            char[] chars = word.toCharArray();
            List<DicNode> values = root.getSon(chars[0]);
            if (values != null){
                for (DicNode value : values) {
                    if (find(word,0,value)){
                        return true;
                    }
                }
    
            }
    
            return false;
        }
    
        public boolean find(String word,int index,DicNode node){
            if (node == null)return false;
            char c = word.charAt(index);
            if (c == '.' || c == node.val){
                if (index == word.length()-1){
                    return node.end;
                }
                List<DicNode> values = node.getSon(word.charAt(index+1));
                if (values != null){
                    for (DicNode value : values) {
                        if (find(word,index+1,value)){
                            return true;
                        }
                    }
                }
    
            }
            return false;
        }
    
        static class DicNode{
    
            char val;
            boolean end;
            Map<Character,DicNode> son;
    
            public DicNode(char val) {
                this.val = val;
                this.son = new HashMap<>();
            }
    
            public List<DicNode> getSon(char c){
                if (c == '.'){
                    return new ArrayList<>(son.values());
                }else {
                    DicNode dicNode = son.get(c);
                    if (dicNode == null)return null;
                    List<DicNode> data= new ArrayList<>();
                    data.add(dicNode);
                    return data;
                }
            }
        }

    329   矩阵最长递增路径

       这题感觉就是记忆画搜索,每次遍历的时候要记住当前值代表的最长递增路径,这样一下次又遍历到这个值的时候就可以直接使用。

        int[][] forward = {{1,0},{0,1},{-1,0},{0,-1}};
        int[][] dp;
        int[][] ma;
        int width,deep;
    
        public int longestIncreasingPath(int[][] matrix) {
            deep = matrix.length;
            width = matrix[0].length;
            dp = new int[deep][width];
            ma = matrix;
            int result = Integer.MIN_VALUE;
            for (int i = 0; i < deep; i++) {
                for (int j = 0; j < width; j++) {
                    result = Math.max(dfs(i,j),result);
                }
            }
            return result;
        }
    
        public int dfs(int x,int y){
            if (dp[x][y] != 0){
                return dp[x][y];
            }
            dp[x][y] = 1;
            for (int[] ints : forward) {
                int tx = x+ints[0],ty = y+ints[1];
                if (tx>=0 && tx <deep && ty>=0 && ty<width && ma[tx][ty] > ma[x][y]){
                    dp[x][y] = Math.max(dp[x][y],dfs(tx,ty)+1);
                }
    
            }
            return dp[x][y];
        }

    491 所有递增子序列

     我的解法效率那是相当低

    public class DFS7 {
    
        public static void main(String[] args) {
            System.out.println(findSubsequences(new int[]{4, 6, 7, 7}));
        }
        public static List<List<Integer>> findSubsequences(int[] nums) {
            Set<List<Integer>> res = new HashSet<>();
            for (int i = 0; i < nums.length; i++) {
                int c = nums[i];
    
                List<List<Integer>> tp = new ArrayList<>();
                for (List<Integer> re : res) {
                    if (c>=re.get(re.size()-1)){
                        List<Integer> list = new ArrayList<>(re);
                        list.add(c);
                        tp.add(list);
                    }
                }
                res.addAll(tp);
                res.add(Arrays.asList(c));
            }
            Iterator<List<Integer>> iterator = res.iterator();
            while (iterator.hasNext()){
                List<Integer> next = iterator.next();
                if (next.size() == 1){
                    iterator.remove();
                }
            }
            List<List<Integer>> resp = new ArrayList<>(res);
            return resp;
        }
    }

      其实这儿涉及到的一个关键点应该是去重,比如 4.6.7.7   就会出现两个47 47,明显不能一起计算,所以如何果能够高效去重应该是很重要的。我用的全局set去重,这样效率非常低。然后看了下官方题解,具体的题解比较长,所以这儿就不贴了,关键在于遍历的时候如何决定是否走当前节点不选择。

     int[] nums;
        List<Integer> tps ;
        List<List<Integer>> res ;
        public List<List<Integer>> findSubsequences(int[] nums) {
            this.nums = nums;
            tps = new ArrayList<>();
            res = new ArrayList<>();
            dsf(0,Integer.MIN_VALUE);
            return res;
        }
    
        public void dsf(int cu,int last){
            if (cu == nums.length){
                if (tps.size() > 1){
                    res.add(new ArrayList<>(tps));
                }
                return;
            }
            int k =nums[cu];
            //选择当前元素
            if (k>=last){
                tps.add(k);
                dsf(cu+1,k);
                tps.remove(tps.size()-1);
            }
            //如果不选择当前元素
            if (k != last)
            dsf(cu+1,last);
    
        }

    494 目标和

       暴力解法应该是如下,官解有动态规划,因为解析比较长这儿就不贴了

    class Solution {
        int result ;
        int nums[];
        int s;
        public int findTargetSumWays(int[] nums, int S) {
            result = 0;
            this.nums = nums;
            s = S;
            dfs(nums[0],1);
            dfs(-nums[0],1);
            return result;
        }
    
        public void dfs(int current,int index){
            if (index == nums.length){
                if (current == s){
                    result++;
                }
                return;
            }
            dfs(current+nums[index],index+1);
            dfs(current-nums[index],index+1);
    
        }
    }

    416  分割等和子集

       看着其实和上题比较像,我的解法如下,但是不知道为何提交成绩很差,好好不容易想到个dp问题的解法,哭辽。。。。

        public boolean canPartition(int[] nums) {
            int total = 0;
            for (int num : nums) {
                total+=num;
            }
            if (nums.length <2 || (total&1)!=0){
                return false;
            }
            int target = total/2;
            boolean[][] dp = new boolean[nums.length][total+1];
            dp[0][nums[0]] = true;
            dp[0][0] = true;
            for (int i = 1; i < nums.length; i++) {
                for (int j = 0; j <= total; j++) {
                    dp[i][j] = dp[i-1][j];
                    if (j>=nums[i]){
                        dp[i][j] |= dp[i-1][j-nums[i]];
                    }
                    if (j == target && dp[i][j]){
                        return true;
                    }
                }
            }
            return dp[nums.length-1][total/2];
        }

      后面查看官方的解才知道因为i只和i-1有关,所以可不用开辟很大的数组空间。并且可以只开辟target大小的数组而不是total,所以根据思路修改了下

     public boolean canPartition(int[] nums) {
            int total = 0;
            int max = Integer.MIN_VALUE;
            for (int num : nums) {
                total+=num;
                max = Math.max(max,num);
            }
            if (nums.length <2 || (total&1)!=0){
                return false;
            }
            int target = total/2;
            if (max>target){
                return false;
            }
            boolean[] pre = new boolean[target+1];
            boolean[] tp = new boolean[target+1];
            pre[nums[0]] = true;
            for (int i = 1; i < nums.length; i++) {
                for (int j = 0; j <= target; j++) {
                    tp[j] = pre[j];
                    if (j>=nums[i]){
                        tp[j] |= pre[j-nums[i]];
                    }
                    if (j == target && tp[j]){
                        return true;
                    }
                }
                pre = tp;
                tp = new boolean[target+1];
            }
            return tp[target];
        }

    547 省份数量

       如果还是像之前的岛屿数量解法明显效率会非常低,因为会进行太多的无用计算。

    public class Collect2 {
        int[][] grid;
        int deep,width;
        public int findCircleNum(int[][] grids) {
            deep = grids.length;
            width = grids[0].length;
            this.grid = grids;
            int result = 0;
            for (int i = 0; i < deep; i++) {
                for (int j = 0; j < width; j++) {
                    if (grid[i][j] == 1){
                        result++;
                        dfs(i,j);
                    }
                }
            }
            return result;
        }
    
        public void dfs(int x,int y){
            grid[x][y] = 0;
            for (int i = x-1; i >= 0 ; i--) {
                if (grid[i][y] == 1){
                    dfs(i,y);
                }
            }
            for (int i = x+1; i < deep; i++) {
                if (grid[i][y] == 1){
                    dfs(i,y);
                }
            }
            for (int i = y-1; i >=0; i--) {
                if (grid[x][i] == 1){
                    dfs(x,i);
                }
            }
            for (int i = y+1; i <width; i++) {
                if (grid[x][i] == 1){
                    dfs(x,i);
                }
            }
        }
    }

       然后看了下官解的思路,感觉自己写的也太low了。

        int[][] grid;
        int deep,width;
        boolean[] visit;
        public int findCircleNum(int[][] grids) {
            deep = grids.length;
            width = grids[0].length;
            this.grid = grids;
    
            visit = new boolean[grids.length];
            int result = 0;
            for (int i = 0; i < grids.length; i++) {
                if (!visit[i]){
                    dfs(i);
                    result++;
                }
            }
    
            return result;
        }
    
        public void dfs(int x){
            for (int i = 0; i < grid.length; i++) {
                if (i != x && !visit[i] && grid[x][i] == 1 ){
                    visit[i] = true;
                    dfs(i);
                }
            }
        }

    51 N皇后问题

    Set<Integer> rows;
        Set<Integer> left;
        Set<Integer> right;
        int width;
        List<List<String>> result;
        public List<List<String>> solveNQueens(int n) {
            rows = new LinkedHashSet<>();
            left = new HashSet<>();
            right = new HashSet<>();
            width = n;
            result = new ArrayList<>();
            dfs(0);
            return result;
        }
    
        public void dfs(int level){
            if (level == width){
                generate();
                return;
            }
            for (int i = 0; i < width; i++) {
                //占用
                if (rows.contains(i) || right.contains(level+i) || left.contains(level-i)){
                    continue;
                }
                right.add(level+i);
                left.add(level-i);
                rows.add(i);
                //下一轮
                dfs(level+1);
                //去掉
                right.remove(level+i);
                left.remove(level-i);
                rows.remove(i);
            }
    
        }
    
        public void generate(){
            List<String> list = new ArrayList<>();
            for (Integer rowIndex : rows) {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < width; i++) {
                    sb.append(rowIndex.equals(i)?"Q":"." );
                }
                list.add(sb.toString());
            }
            result.add(list);
        }
  • 相关阅读:
    shell脚本编程练习
    linux中()、[]、{}、(())、[[]]等各种括号的使用
    Linux Shell 变量自加
    while read line [linux] shell 学习
    踢出某正在访问的用户||永久禁止某IP访问
    linux设置 自定义脚本开机启动
    syntax error: unexpected end of file完美解决方案
    Linux利用nc命令脚本批量检测服务器指定端口是否开放
    41-贪心算法
    38-动态规划
  • 原文地址:https://www.cnblogs.com/hetutu-5238/p/14473202.html
Copyright © 2020-2023  润新知