zoukankan      html  css  js  c++  java
  • 二维数组搜索FloodFill算法

    1.具体问题

    二维数组的搜索问题,二维数组可以看成四叉树进行搜索。

    • 图像渲染
    • 自动魔棒功能
    • 扫雷

    2.图像渲染问题

    有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 $0$$65535$ 之间。

    给你一个坐标$(sr, sc)$表示图像渲染开始的像素值(行 ,列)和一个新的颜色值$newColor$,让你重新上色这幅图像。

    为了完成上色工作,从初始坐标开始,记录初始坐标的上下左右四个方向上像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应四个方向上像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为新的颜色值。

    最后返回经过上色渲染后的图像。

    2.1 深度优先搜索

    func floodFill(image [][]int, sr int, sc int, newColor int) [][]int {
    	startColor := image[sr][sc]
    	var dfs func(int, int)
    	dfs = func(i, j int) {
    		if i < 0 || j < 0 || i >= len(image) || j >= len(image[0]) {
    			return
    		}
    		if image[i][j] != startColor {
    			return
    		}
    		if image[i][j] == -1 { // 已经访问过了
    			return
    		}
    		image[i][j] = -1 // 标记已经访问过了 防止原始颜色和新颜色一个值时 递归出不来
    		dfs(i-1, j)
    		dfs(i+1, j)
    		dfs(i, j-1)
    		dfs(i, j+1)
    		image[i][j] = newColor
    	}
    	dfs(sr, sc)
    	return image
    }
    

    注意细节:如果起始颜色与新颜色同色时,会重复访问以前访问过的位置,这时访问过的位置要加标志才可以,这里利用回溯进行标记,很巧妙。

    2.2 广度优先搜索

    发散状搜索

    type pos struct {
    	i int
    	j int
    }
    
    // 广度优先搜索
    func floodFill(image [][]int, sr int, sc int, newColor int) [][]int {
    	startColor := image[sr][sc]
    	offset := [][]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}
    	visted := make([][]bool, len(image))
    	for i := 0; i < len(visted); i++ {
    		visted[i] = make([]bool, len(image[0]))
    	}
    	queue := []pos{}
    	queue = append(queue, pos{sr, sc})
    	for len(queue) != 0 {
    		cur := queue[0] // 出队
    		queue = queue[1:]
    		if cur.i < 0 || cur.j < 0 || cur.i >= len(image) || cur.j >= len(image[0]) {
    			continue
    		}
    		if image[cur.i][cur.j] != startColor {
    			continue
    		}
    		if visted[cur.i][cur.j] {
    			continue
    		}
    		image[cur.i][cur.j] = newColor
    		visted[cur.i][cur.j] = true
    		for k := 0; k < len(offset); k++ {
    			queue = append(queue, pos{cur.i + offset[k][0], cur.j + offset[k][1]}) // 入队
    		}
    	}
    	return image
    }
    
  • 相关阅读:
    Tomcat服务器原理详解
    junit入门
    lombok
    java 运行指定类的main函数
    席位分配问题——惯例Q值法和d&#39;hondt法的MATLAB程序
    5.2 calendar--通用日期的相关函数(3)
    [笔记]软件体系结构(1)--模式初印象
    hdu 1003
    linux虚拟机上挂载U盘
    Android中Java与web通信
  • 原文地址:https://www.cnblogs.com/lsyy2020/p/14853978.html
Copyright © 2011-2022 走看看