• floodfill算法(洪水灌溉算法)


    一)floodfill算法简介:

    二)图像渲染

    733. 图像渲染 - 力扣(LeetCode)

    1. class Solution {
    2. int[] dx = {1, 0, 0, -1};
    3. int[] dy = {0, 1, -1, 0};
    4. //上下搜索的时候要使用向量数组
    5. int row=0;
    6. int col=0;
    7. int target=0;
    8. public void dfs(int[][] image,int i,int j,int color){
    9. if(image[i][j]==target){
    10. image[i][j]=color;
    11. }
    12. for(int k=0;k<4;k++){
    13. int x=i+dx[k];
    14. int y=j+dy[k];
    15. if(x>=0&&x=0&&y
    16. //四个方向进行深度优先遍历
    17. dfs(image,x,y,color);
    18. }
    19. }
    20. }
    21. public int[][] floodFill(int[][] image, int i, int j, int color) {
    22. if(color==image[i][j]) return image;//防止走到重复元素的情况
    23. this.target=image[i][j];
    24. this.row=image.length;
    25. this.col=image[0].length;
    26. dfs(image,i,j,color);
    27. return image;
    28. }
    29. }

    三)岛屿数量

    200. 岛屿数量 - 力扣(LeetCode)

    1. class Solution {
    2. public boolean[][] check;
    3. int[] dx = {1, 0, 0, -1};
    4. int[] dy = {0, 1, -1, 0};
    5. int row=0;
    6. int col=0;
    7. public void dfs(char[][] array,int i,int j){
    8. check[i][j]=true;
    9. for(int k=0;k<4;k++){
    10. int x=i+dx[k];
    11. int y=j+dy[k];
    12. if(x>=0&&x=0&&y'1'&&check[x][y]==false){
    13. check[x][y]=true;
    14. dfs(array,x,y);
    15. }
    16. }
    17. }
    18. public int numIslands(char[][] array) {
    19. this.row=array.length;
    20. this.col=array[0].length;
    21. this.check=new boolean[row][col];
    22. int ret=0;
    23. for(int i=0;i
    24. for(int j=0;j
    25. if(array[i][j]=='1'&&check[i][j]==false){
    26. check[i][j]=true;
    27. ret++;
    28. dfs(array,i,j);
    29. }
    30. }
    31. }
    32. return ret;
    33. }
    34. }

    四)岛屿的最大面积:

    ​​​​​​695. 岛屿的最大面积 - 力扣(LeetCode)

    算法原理:

    1)想要解决本题核心的思路还是做一次深度优先遍历,我们一开始来遍历这个岛屿,当扫描到一个陆地之后(这个数组的值等于1),就从这个陆地也就是1开始来做一次深度优先遍历,上下左右都来进行扫描

    2)此时定义一个全局的变量count,在深度优先遍历,只要进入一次dfs,就让这个count++,因为在每一次进入到dfs函数的时候,都是相当于是进入到了一块陆地,档次是针对这个起始陆地深度优先遍历完成之后,此时的这个count值就是统计这块岛屿的面积,然后再使用ret统计最终的结果;

    3)下面的写法是dfs带有返回值和dfs不带有返回值的写法:

    1. class Solution {
    2. public boolean[][] check;
    3. int[] dx = {1, 0, 0, -1};
    4. int[] dy = {0, 1, -1, 0};
    5. int row=0;
    6. int col=0;
    7. int ret=0;
    8. int count=0;
    9. public void dfs(int[][] array,int i,int j){
    10. count++;
    11. for(int k=0;k<4;k++){
    12. int x=i+dx[k];
    13. int y=j+dy[k];
    14. if(x>=0&&x=0&&y1&&check[x][y]==false){
    15. check[x][y]=true;
    16. dfs(array,x,y);
    17. }
    18. }
    19. }
    20. public int maxAreaOfIsland(int[][] array) {
    21. this.row=array.length;
    22. this.col=array[0].length;
    23. this.check=new boolean[row][col];
    24. for(int i=0;i
    25. for(int j=0;j
    26. if(array[i][j]==1&&check[i][j]==false){
    27. check[i][j]=true;
    28. count=0;
    29. dfs(array,i,j);
    30. ret=Math.max(count,ret);
    31. }
    32. }
    33. }
    34. return ret;
    35. }
    36. }
    1. class Solution {
    2. public boolean[][] check;
    3. int[] dx = {1, 0, 0, -1};
    4. int[] dy = {0, 1, -1, 0};
    5. int row=0;
    6. int col=0;
    7. int ret=0;
    8. public int dfs(int[][] array,int i,int j){
    9. int count=1;
    10. for(int k=0;k<4;k++){
    11. int x=i+dx[k];
    12. int y=j+dy[k];
    13. if(x>=0&&x=0&&y1&&check[x][y]==false){
    14. check[x][y]=true;
    15. count+=dfs(array,x,y);
    16. }
    17. }
    18. return count;
    19. }
    20. public int maxAreaOfIsland(int[][] array) {
    21. this.row=array.length;
    22. this.col=array[0].length;
    23. this.check=new boolean[row][col];
    24. for(int i=0;i
    25. for(int j=0;j
    26. if(array[i][j]==1&&check[i][j]==false){
    27. check[i][j]=true;
    28. ret=Math.max(dfs(array,i,j),ret);
    29. }
    30. }
    31. }
    32. return ret;
    33. }
    34. }

    五)被围绕的区域

    130. 被围绕的区域 - 力扣(LeetCode)

    算法原理:

    1)首先遍历整个二维矩阵的边界,先找到边界区域的圆圈,先进行标记一下,那么剩下的圆圈自然就是在内部的圆圈,标记的时候可以搞一个check数组,也可以把边界的情况处理成一个额外字符

    2)然后直接修改内部的圆圈;

    1. class Solution {
    2. public boolean[][] check;
    3. public int row=0;
    4. public int col=0;
    5. int[] dx = {1, 0, 0, -1};
    6. int[] dy = {0, 1, -1, 0};
    7. public void dfs(char[][] board,int i,int j,char ch){
    8. check[i][j]=true;
    9. board[i][j]=ch;
    10. for(int k=0;k<4;k++){
    11. int x=i+dx[k];
    12. int y=j+dy[k];
    13. if(x>=0&&x=0&&y'O'&&check[x][y]==false){
    14. dfs(board,x,y,ch);
    15. }
    16. }
    17. }
    18. public void solve(char[][] board) {
    19. //1.先进行初始化操作
    20. this.row=board.length;
    21. this.col=board[0].length;
    22. this.check=new boolean[row][col];
    23. //2.进行处理边界情况下的O字符
    24. for(int i=0;i
    25. if(board[0][i]=='O'&&check[0][i]==false){
    26. dfs(board,0,i,'O');
    27. }
    28. if(board[row-1][i]=='O'&&check[row-1][i]==false){
    29. dfs(board,row-1,i,'O');
    30. }
    31. }
    32. for(int j=0;j
    33. if(board[j][0]=='O'&&check[j][0]==false){
    34. dfs(board,j,0,'O');
    35. }
    36. if(board[j][col-1]=='O'&&check[j][col-1]==false){
    37. dfs(board,j,col-1,'O');
    38. }
    39. }
    40. System.out.println(Arrays.deepToString(check));
    41. //3.开始处理非边界上的O
    42. for(int i=0;i
    43. for(int j=0;j
    44. if(board[i][j]=='O'&&check[i][j]==false){
    45. dfs(board,i,j,'X');
    46. }
    47. }
    48. }
    49. }
    50. }

    六)太平洋大西洋水流问题

    417. 太平洋大西洋水流问题 - 力扣(LeetCode)

    解法1:直接来解决这个问题,直接进行遍历二维数组中的每一个点,直接判断某一个点是否能够到达太平洋也可以到达大西洋,但是可能会出现重复路径的情况,所以说时间有可能会超时

    解法2:正难则反:反着看,假设太平洋或者是大西洋的水能够逆着来,能够走到哪些位置,直接看大于等于当前位置的位置此时我们枚举完成第一行和最后一行的所有元素,并且针对与这些所有元素全部做一次深度优先遍历,将所有能够流向大西洋的点进行标记

    1. class Solution {
    2. List> ret=new ArrayList<>();
    3. int row=0;
    4. int col=0;
    5. int[] dx = {1, 0, 0, -1};
    6. int[] dy = {0, 1, -1, 0};
    7. public void dfs(int[][] array,int i,int j,boolean[][] check){
    8. check[i][j]=true;
    9. for(int k=0;k<4;k++){
    10. int x=i+dx[k];
    11. int y=j+dy[k];
    12. if(x>=0&&x=0&&yfalse&&array[i][j]<=array[x][y]){
    13. dfs(array,x,y,check);
    14. }
    15. }
    16. }
    17. public List> pacificAtlantic(int[][] array) {
    18. this.row=array.length;
    19. this.col=array[0].length;
    20. boolean[][] pac=new boolean[row][col];
    21. boolean[][] atc=new boolean[row][col];
    22. //1.先处理太平洋
    23. for(int i=0;i
    24. dfs(array,0,i,pac);//处理上边界,上边界是找所有可能从大西洋从(i,j)方向逆流到哪一个位置
    25. }
    26. for(int j=0;j
    27. dfs(array,j,0,pac);//处理左边界
    28. }
    29. //2.再来处理大西洋
    30. for(int i=0;i
    31. dfs(array,row-1,i,atc);//处理下边界
    32. }
    33. for(int j=0;j
    34. dfs(array,j,col-1,atc);//处理右边界,右边界是找所有可能从大西洋从(i,j)方向逆流到哪一个位置
    35. }
    36. //3.最后进行提取结果
    37. for(int i=0;i
    38. for(int j=0;j
    39. if(pac[i][j]==true&&atc[i][j]==true){
    40. List temp=new ArrayList<>();
    41. temp.add(i);
    42. temp.add(j);
    43. ret.add(temp);
    44. }
    45. }
    46. }
    47. //4.返回最终结果
    48. return ret;
    49. }
    50. }

    七)扫雷游戏

    529. 扫雷游戏 - 力扣(LeetCode)

    一)题目解析:

    1)刚一开始,这道题给了我们原始的一个字符矩阵,这个矩阵代表的是扫雷的棋盘,然后会继续给我们一个中心点告诉我们要开始进行点击的位置,点击之后通过下面一系列的规则把点击之后的结果给展示出来,然后返回最终结果即可

    2)如果此时如果某一个地雷没有被挖出的时候,此时的这个位置就被标记成了一个M,E这个字符表示没有被挖出的空格,E表示此时还没有被搜索到的区域,在没有正式的点击棋盘之前,除了地雷的位置被标记成一个M之外,其余的地方都被标记成了E,当进行点击之后,B表示的是已经被挖出的方块,代表没有相邻上,下,左,右,和所有4个对角线地雷的已挖出的空白方块,数字1-8代表周围地雷的个数,X代表已经被挖出的地雷,如果玩家直接点击地雷的位置,直接把对应的位置标记成X,返回即可

    3)此时就拿我们题目中给定的实例来说,当进行点击(3,0)这个位置的时候,就会上下左右的递归地将所有的空方格全部展开,一旦出现了别的空方格,又会递归地展开;

    4)但是此时如果出现展开一个空方格,它的周围有地雷,那么就直接修改它的数字即可,修改成他最近的地雷数

    二)算法原理:

    1)当进行点击某一个位置之后,首先判断这个点击的位置,当点击的这个位置周围没有地雷,那么它就是空方格,如果发现这个空方格子周围没有地雷,那么我们就需要递归性的把它周围的空方格全部打开,并且将格子内的字符修改成B

    2)如果发现这个空格子上下左右有地雷,那么就直接将我当前的这个位置修改成周围地雷的个数,然后会返回;

    3)但是这个题和之前的题有一些不同,之前我们是进行扩展四个位置,但是此时我们是需要进行扩展8个位置

    1. class Solution {
    2. int[] dx = {0, 1, 0, -1, 1, 1, -1, -1};
    3. int[] dy = {1, 0, -1, 0, 1, -1, 1, -1};
    4. int row=0;
    5. int col=0;
    6. public void dfs(char[][] board,int i,int j){
    7. //1.先考虑这个空格子周围是否存在地雷
    8. int count=0;
    9. for(int k=0;k<8;k++){
    10. int x=i+dx[k];
    11. int y=j+dy[k];
    12. if(x>=0&&x=0&&y
    13. if(board[x][y]=='M'){
    14. count++;
    15. }
    16. }
    17. }
    18. //2.根据雷的数目来更新这个值是否填充数字还是填充一个字符B
    19. if(count==0){
    20. board[i][j]='B';
    21. for(int k=0;k<8;k++){
    22. int x=i+dx[k];
    23. int y=j+dy[k];
    24. if(x>=0&&x=0&&y'E'){
    25. dfs(board,x,y);
    26. }
    27. }
    28. }else{
    29. board[i][j]=(char)(count+'0');
    30. }
    31. }
    32. public char[][] updateBoard(char[][] board, int[] click) {
    33. //1.先进行初始化全局变量的初始化
    34. this.row=board.length;
    35. this.col=board[0].length;
    36. int taregtX=click[0];
    37. int taregtY=click[1];
    38. //2.先处理点击地雷的情况
    39. if(board[taregtX][taregtY]=='M'){//当前这个位置没有被扫描过
    40. board[taregtX][taregtY]='X';
    41. return board;
    42. }
    43. //3.再来处理空格的情况
    44. dfs(board,taregtX,taregtY);
    45. return board;
    46. }
    47. }

    八)机器人的运动范围

    剑指 Offer 13. 机器人的运动范围 - 力扣(LeetCode)

    1. class Solution {
    2. int row=0;
    3. int col=0;
    4. int max=0;
    5. int count=0;
    6. boolean[][] check;
    7. int[] dx = {1, 0, 0, -1};
    8. int[] dy = {0, 1, -1, 0};
    9. public boolean check(int x,int y){
    10. //将两个数的所有位数之和加起来
    11. int sum=0;
    12. while(x>0){
    13. sum+=x%10;
    14. x/=10;
    15. }
    16. while(y>0){
    17. sum+=y%10;
    18. y/=10;
    19. }
    20. return sum<=max;
    21. }
    22. public void dfs(int i,int j){
    23. count++;
    24. for(int k=0;k<4;k++){
    25. int x=i+dx[k];
    26. int y=j+dy[k];
    27. if(x>=0&&x=0&&ytrue&&check[x][y]==false){
    28. check[x][y]=true;
    29. dfs(x,y);
    30. }
    31. }
    32. }
    33. public int movingCount(int m, int n, int k) {
    34. this.row=m;
    35. this.col=n;
    36. this.max=k;
    37. this.check=new boolean[row][col];
    38. if(k>=0) check[0][0]=true;
    39. dfs(0,0);
    40. return count;
    41. }
    42. }

  • 相关阅读:
    linq to sql性能优化技巧
    4_1_linux
    python每日一题【剑指 Offer 48. 最长不含重复字符的子字符串】
    力扣labuladong——一刷day44
    TSINGSEE青犀省级高速公路视频上云联网方案:全面实现联网化、共享化、智能化
    大语言模型LLM Pro+中Pro+(Prompting)的意义
    Rasa 使用ResponseSelector实现FAQ和闲聊
    链表
    已解决selenium.common.exceptions.TimeoutException: Message: script timeout
    使用 OpenCV 测量物体尺寸
  • 原文地址:https://blog.csdn.net/weixin_61518137/article/details/132772993