洪水填充问题

  洪水填充是在图中常用的技巧,在遍历图的过程中,修改路径信息来剪枝,类似染色,使得每一

片区域可以得到区分。其时间复杂度和图的规模是相同的

岛屿的数量

class Solution {
public:
    void f(vector<vector<char>>& grid, int i, int j) {
        if (i < 0 || i >= grid.size() || j < 0 || j >= grid[0].size() ||
            grid[i][j] != '1')
            return;
        grid[i][j] = 0;
        f(grid, i - 1, j);
        f(grid, i + 1, j);
        f(grid, i, j + 1);
        f(grid, i, j - 1);
    }
    int numIslands(vector<vector<char>>& grid) {
        int ans = 0;
        for (int i = 0; i < grid.size(); i++) {
            for (int j = 0; j < grid[0].size(); j++) {
                if (grid[i][j] == '1') {
                    ans++;
                    f(grid, i, j);
                }
            }
        }
        return ans;
    }
};

此题是一个模板题,设置f函数进行dfs,将一片区域的点全部染色并加以区分

被围绕的区域

public class Solution{

	public static void solve(char[][] board) {
		int n = board.length;
		int m = board[0].length;
		for (int j = 0; j < m; j++) {
			if (board[0][j] == 'O') {
				dfs(board, n, m, 0, j);
			}
			if (board[n - 1][j] == 'O') {
				dfs(board, n, m, n - 1, j);
			}
		}
		for (int i = 1; i < n - 1; i++) {
			if (board[i][0] == 'O') {
				dfs(board, n, m, i, 0);
			}
			if (board[i][m - 1] == 'O') {
				dfs(board, n, m, i, m - 1);
			}
		}
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (board[i][j] == 'O') {
					board[i][j] = 'X';
				}
				if (board[i][j] == 'F') {
					board[i][j] = 'O';
				}
			}
		}
	}

	public static void dfs(char[][] board, int n, int m, int i, int j) {
		if (i < 0 || i == n || j < 0 || j == m || board[i][j] != 'O') {
			return;
		}
		board[i][j] = 'F';
		dfs(board, n, m, i + 1, j);
		dfs(board, n, m, i - 1, j);
		dfs(board, n, m, i, j + 1);
		dfs(board, n, m, i, j - 1);
	}

}

此题就是将不与边界相连的区域修改。要去找不与边界相连的区域较难,可以先将与边界相连的区域染色,剩下的就是边界内的,遍历进行修改

最大人工岛

class Solution {
public:
    int sign = 2;
    int count = 0;
    void f(vector<vector<int>>& grid, int i, int j) {
        if (i < 0 || i >= grid.size() || j < 0 || j >= grid[0].size() ||
            grid[i][j] != 1)
            return;
        grid[i][j] = sign;
        count++;
        f(grid, i, j - 1);
        f(grid, i, j + 1);
        f(grid, i - 1, j);
        f(grid, i + 1, j);
    }
    int ans = 0;
    int largestIsland(vector<vector<int>>& grid) {
        unordered_map<int, int> rem;
        for (int i = 0; i < grid.size(); i++) {
            for (int j = 0; j < grid[0].size(); j++) {
                if (grid[i][j] == 1) {
                    f(grid, i, j);
                    rem[sign] = count;
                    sign++;
                    ans = max(ans, count);
                    count = 0;
                }
            }
        }
        unordered_set<int> visit;
        for (int i = 0; i < grid.size(); i++) {
            for (int j = 0; j < grid[0].size(); j++) {
                if (grid[i][j] == 0) {
                    int cur = 0;
                    if (i > 0 && grid[i - 1][j] != 0 &&
                        visit.find(grid[i - 1][j]) == visit.end()) {
                        visit.insert(grid[i - 1][j]);
                        cur += rem[grid[i - 1][j]];
                    }
                    if (i < grid.size() - 1 && grid[i + 1][j] != 0 &&
                        visit.find(grid[i + 1][j]) == visit.end()) {
                        visit.insert(grid[i + 1][j]);
                        cur += rem[grid[i + 1][j]];
                    }
                    if (j > 0 && grid[i][j - 1] != 0 &&
                        visit.find(grid[i][j - 1]) == visit.end()) {
                        visit.insert(grid[i][j - 1]);
                        cur += rem[grid[i][j - 1]];
                    }
                    if (j < grid[0].size() - 1 && grid[i][j + 1] != 0 &&
                        visit.find(grid[i][j + 1]) == visit.end()) {
                        visit.insert(grid[i][j + 1]);
                        cur += rem[grid[i][j + 1]];
                    }
                    ans = max(ans, cur + 1);
                    visit.clear();
                }
            }
        }
        return ans;
    }
};

填充一个格,求填充之后最大的连通面积。可以先将不同的区域进行统计并染色,然后遍历数组依次尝试并找出最大值

打砖块

class Solution {
public:
    int dfs(vector<vector<int>>& grid, int i, int j) {
        if (i < 0 || i >= grid.size() || j < 0 || j >= grid[0].size() ||
            grid[i][j] != 1)
            return 0;
        grid[i][j] = 2;
        return 1 + dfs(grid, i + 1, j) + dfs(grid, i - 1, j) +
               dfs(grid, i, j + 1) + dfs(grid, i, j - 1);
    }
    bool judge(vector<vector<int>>& grid, int x, int y) {
        if (grid[x][y] == 1 &&
            (x == 0 || (x > 0 && grid[x - 1][y] == 2) ||
             (x < grid.size() - 1 && grid[x + 1][y] == 2) ||
             (y > 0 && grid[x][y - 1] == 2) ||
             (y < grid[0].size() - 1 && grid[x][y + 1] == 2)))
            return true;
        return false;
    }
    vector<int> hitBricks(vector<vector<int>>& grid,
                          vector<vector<int>>& hits) {
        int n = grid.size(), m = grid[0].size();
        vector<int> ans(hits.size(), 0);
        if (n == 1)
            return ans;
        for (auto i : hits) {
            grid[i[0]][i[1]]--;
        }
        for (int i = 0; i < m; i++)
            dfs(grid, 0, i);
        for (int i = hits.size() - 1; i >= 0; i--) {
            int x = hits[i][0];
            int y = hits[i][1];
            grid[x][y]++;
            if (judge(grid, x, y)) {
                int cur = dfs(grid, x, y) - 1;
                ans[i] = cur;
            }
        }
        return ans;
    }
};

打砖块的时间是有时间循序的,对于一个时间点打掉的砖块,跟之前打掉的砖块和与之相连的砖块是有关的,正向思考是不容易做的,可以逆向思考,先将要打掉的砖块标记,然后从最晚时间打掉的砖块开始向前填充他能打掉的砖块并记录(只有这个砖块的相邻砖块有不掉落的或者他本是就是在天花板上的砖块才可以),只要在符合条件那么他周围可以掉的砖块都是他要打掉的因为既然这些砖块与最晚打掉的砖块相连,即使他们和较早时间打掉的砖块相连,那也不会让较早时间打掉的砖块打掉。这种技巧叫做"时间倒流"技巧,在涉及先后顺序的题中是常用的技巧

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
洪水填充算法(Flood Fill)是一种图像处理算法,它通过指定一个起始点和一个目标颜色,将所有与起始点颜色相同的区域都填充成指定的目标颜色。在Python中,可以使用递归来实现洪水填充算法。 根据引用\[1\]中提供的信息,我们可以使用以下代码实现洪水填充算法: ```python def flood_fill(image, start_x, start_y, target_color, replacement_color): if image\[start_x\]\[start_y\] != target_color: return image\[start_x\]\[start_y\] = replacement_color if start_x > 0: flood_fill(image, start_x - 1, start_y, target_color, replacement_color) if start_x < len(image) - 1: flood_fill(image, start_x + 1, start_y, target_color, replacement_color) if start_y > 0: flood_fill(image, start_x, start_y - 1, target_color, replacement_color) if start_y < len(image\[0\]) - 1: flood_fill(image, start_x, start_y + 1, target_color, replacement_color) ``` 在引用\[2\]中提到的问题中,可能是代码中的某些问题导致了错误。可以检查代码中是否正确导入了pygame库,并确保代码中的变量和函数调用正确无误。 总结来说,洪水填充算法是一种用于图像处理的算法,可以通过指定起始点和目标颜色来填充图像中的区域。在Python中,可以使用递归来实现该算法。如果在实际应用中遇到问题,可以检查代码中的错误或者调试环境是否正常。 #### 引用[.reference_title] - *1* *3* [Python实现泛洪填充算法类(附完整源代码)](https://blog.csdn.net/update7/article/details/131496703)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [python中的洪水填充算法崩溃](https://blog.csdn.net/weixin_39847887/article/details/114396656)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值