[高频] 五. 如何高效实现搜索类题目

来源:互联网 发布:淘宝信用借贷逾期 编辑:程序博客网 时间:2024/06/06 09:23

130. Sorrounded Regions:  点击打开链接

思路:从四个最外边向里面搜索,只要是遇到'O',就是可以从外面走通的,装入queue

         将搜过的为'O'的元素进行遍历,并标记为true,

         找它的四个邻居点,如果在边界点之内为'O'并且是没有标记为true的,要做标记等待被遍历

         最后将没有标记成true的'O'标记为'X',这些是内部围着的'X',返回地图

class Pair{    int x;    int y;    Pair(int x, int y){        this.x = x;        this.y = y;    }}public class Solution {    /**     * @param board a 2D board containing 'X' and 'O'     * @return void     */        public void surroundedRegions(char[][] board) {        if(board==null || board.length == 0) return;        boolean[][] marked = new boolean[board.length][board[0].length];        Queue<Pair> queue = new LinkedList<Pair>();        int[] dx = {-1, 1, 0, 0};        int[] dy = {0, 0, -1, 1};               for(int i = 0; i < board[0].length; i++){                        //最上,最下两条边            if(board[0][i] == 'O'){                queue.offer(new Pair(0, i));            }            if(board[board.length - 1][i] == 'O'){                queue.offer(new Pair(board.length - 1, i));            }        }                for(int j = 0; j < board.length; j++){                           //最左,最右两条边            if(board[j][0] == 'O'){                queue.offer(new Pair(j, 0));            }            if(board[j][board[0].length - 1] == 'O'){                queue.offer(new Pair(j, board[0].length - 1));            }        }                while(!queue.isEmpty()){            Pair current = queue.poll();            marked[current.x][current.y] = true;                         //每次poll出来的标记为true            for(int k = 0; k < 4; k++){                int newX=current.x + dx[k];                int newY=current.y + dy[k];                Pair newP=new Pair(newX,newY);                if(isValid(board, newP)){                    if(board[newX][newY] == 'O' && !marked[newX][newY]){                        queue.add(newP);                                                }                }            }        }                for(int i = 0; i < board.length; i++){                           //剩余没被标记为true的'O',都要标记为'X'            for(int j = 0; j < board[0].length; j++){                if(board[i][j] == 'O' && !marked[i][j]){                    board[i][j] = 'X';                }            }        }    }        private boolean isValid(char[][] board,Pair p){        if(p.x<0 || p.x>=board.length){            return false;        }        if(p.y<0 || p.y>=board[0].length){            return false;        }        return true;    }}

663. Nearest Exit:  点击打开链接

思路:遍历整个matrix拿到所有gate,BFS所有gate点,如果四周有有效的INF点,INF的值更新为gate值+1

注意:已经更新的INF点,就不用再更新,即使以后的遍历恰好是别的gate的四周点,因为要求离门最近的距离,越先被更新说明离门越近

         obsatcle点不用管,一开始我也是对obstacle不知道怎么处理

class Point{    int x;    int y;    Point(int x,int y){        this.x=x;        this.y=y;    }}public class Solution {    /**     * @param rooms m x n 2D grid     * @return nothing     */    public void wallsAndGates(int[][] rooms) {        if(rooms==null || rooms.length==0){            return;        }        final int INF = 2147483647;        int[] dx={0,0,-1,1};        int[] dy={1,-1,0,0};        Queue<Point> queue=new LinkedList<>();        for(int i=0;i<rooms.length;i++){            for(int j=0;j<rooms[0].length;j++){                if(rooms[i][j]==0){                    queue.offer(new Point(i,j));                }            }        }                while(!queue.isEmpty()){            Point p=queue.poll();            for(int i=0;i<4;i++){                int newX=p.x+dx[i];                int newY=p.y+dy[i];                Point newP=new Point(newX,newY);                if(isValid(rooms,newP)){                    if(rooms[newX][newY]==INF){                        queue.offer(newP);                        rooms[newX][newY]=rooms[p.x][p.y]+1;                //一层一层的值不断累加                    }                }            }        }    }        private boolean isValid(int[][] rooms,Point p){        if(p.x<0 || p.x>=rooms.length){            return false;        }        if(p.y<0 || p.y>=rooms[0].length){            return false;        }        return true;    }}

425. Letter Combinations of a Phone Number: 点击打开链接

思路:枚举型dfs

时间:O(3^n),每一层有三种选择,一共有n层

public class Solution {    /**     * @param digits A digital string     * @return all posible letter combinations     */    ArrayList<String> result=new ArrayList<>();    public ArrayList<String> letterCombinations(String digits) {        if(digits==null || digits.length()==0){            return result;        }                String[] array=new String[]{"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};          dfs(0,digits.length(),"",digits,array);        return result;    }        private void dfs(int n,int len,String str,String digits,String[] array){  //无脑地放入所有所需参数        if(n==len){                                                           //再写退出情况            result.add(str);              return;        }                int digit=digits.charAt(n)-'0';                                       //先写扩展情况        for(char c:array[digit].toCharArray()){            dfs(n+1,len,str+c,digits,array);                                  //String可以直接加char,int        }    }}

652. Factorization: 点击打开链接

public class Solution {    /**     * @param n an integer     * @return a list of combination     */    List<List<Integer>> result=new ArrayList<>();    List<Integer> list=new ArrayList<>();    public List<List<Integer>> getFactors(int n) {        if(n<=1){            return result;        }        dfs(2,n);        return result;    }        private void dfs(int lastF,int remain){        if(!list.isEmpty()){            list.add(remain);                                        //判断的时候才装remain            result.add(new ArrayList<Integer>(list));            list.remove(list.size()-1);                              //装到result链之后还要remove        }                for(int i=lastF;i<=remain/i;i++){                            //能保证每个list顺序是non-descending order            if(remain%i==0){                                         //也能保证后面的[6,2]不要,和[2,6]不重复                list.add(i);                dfs(i,remain/i);                list.remove(list.size()-1);            }        }    }}

653. Add Operators: 点击打开链接

注意:String转化为int很容易溢出,因此要用long

public class Solution {    /**     * @param num a string contains only digits 0-9     * @param target an integer     * @return return all possibilities     */    public List<String> addOperators(String num, int target) {        List<String> result=new ArrayList<>();        if(num==null || num.length()==0){            return result;        }        dfs(result,num,target,"",0,0,0);        return result;    }        private void dfs(List<String> result,String num, int target,String path,int pos,long sum,long lastF){        if(pos==num.length()){            if(sum==target){                result.add(path);            }        }                for(int i=pos;i<num.length();i++){            long cur=Long.valueOf(num.substring(pos,i+1));            if(pos==0){                                                         //第一个数字前不能有符号                dfs(result,num,target,path+cur,i+1,cur,cur);            }else{                dfs(result,num,target,path+"+"+cur,i+1,sum+cur,cur);                dfs(result,num,target,path+"-"+cur,i+1,sum-cur,-cur);                dfs(result,num,target,path+"*"+cur,i+1,sum-lastF+lastF*cur,lastF*cur);            }            if(num.charAt(pos)=='0'){                                           //数字不能有前导零                break;            }        }    }}
634. Word Squares:点击打开链接





原创粉丝点击