返回介绍

solution / 0700-0799 / 0733.Flood Fill / README

发布于 2024-06-17 01:03:35 字数 8913 浏览 0 评论 0 收藏 0

733. 图像渲染

English Version

题目描述

有一幅以 m x n 的二维整数数组表示的图画 image ,其中 image[i][j] 表示该图画的像素值大小。

你也被给予三个整数 srscnewColor 。你应该从像素 image[sr][sc] 开始对图像进行 上色填充

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

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

 

示例 1:

输入: image = [[1,1,1],[1,1,0],[1,0,1]],sr = 1, sc = 1, newColor = 2
输出: [[2,2,2],[2,2,0],[2,0,1]]
解析: 在图像的正中间,(坐标(sr,sc)=(1,1)),在路径上所有符合条件的像素点的颜色都被更改成2。
注意,右下角的像素没有更改为2,因为它不是在上下左右四个方向上与初始点相连的像素点。

示例 2:

输入: image = [[0,0,0],[0,0,0]], sr = 0, sc = 0, newColor = 2
输出: [[2,2,2],[2,2,2]]

 

提示:

  • m == image.length
  • n == image[i].length
  • 1 <= m, n <= 50
  • 0 <= image[i][j], newColor < 216
  • 0 <= sr < m
  • 0 <= sc < n

解法

方法一:Flood fill 算法

Flood fill 算法是从一个区域中提取若干个连通的点与其他相邻区域区分开(或分别染成不同颜色)的经典算法。因为其思路类似洪水从一个区域扩散到所有能到达的区域而得名。

最简单的实现方法是采用 DFS 的递归方法,也可以采用 BFS 的迭代来实现。

时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为图像的行数和列数。

class Solution:
  def floodFill(
    self, image: List[List[int]], sr: int, sc: int, color: int
  ) -> List[List[int]]:
    def dfs(i, j):
      if (
        not 0 <= i < m
        or not 0 <= j < n
        or image[i][j] != oc
        or image[i][j] == color
      ):
        return
      image[i][j] = color
      for a, b in pairwise(dirs):
        dfs(i + a, j + b)

    dirs = (-1, 0, 1, 0, -1)
    m, n = len(image), len(image[0])
    oc = image[sr][sc]
    dfs(sr, sc)
    return image
class Solution {
  private int[] dirs = {-1, 0, 1, 0, -1};
  private int[][] image;
  private int nc;
  private int oc;

  public int[][] floodFill(int[][] image, int sr, int sc, int color) {
    nc = color;
    oc = image[sr][sc];
    this.image = image;
    dfs(sr, sc);
    return image;
  }

  private void dfs(int i, int j) {
    if (i < 0 || i >= image.length || j < 0 || j >= image[0].length || image[i][j] != oc
      || image[i][j] == nc) {
      return;
    }
    image[i][j] = nc;
    for (int k = 0; k < 4; ++k) {
      dfs(i + dirs[k], j + dirs[k + 1]);
    }
  }
}
class Solution {
public:
  vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
    int m = image.size(), n = image[0].size();
    int oc = image[sr][sc];
    int dirs[5] = {-1, 0, 1, 0, -1};
    function<void(int, int)> dfs = [&](int i, int j) {
      if (i < 0 || i >= m || j < 0 || j >= n || image[i][j] != oc || image[i][j] == color) {
        return;
      }
      image[i][j] = color;
      for (int k = 0; k < 4; ++k) {
        dfs(i + dirs[k], j + dirs[k + 1]);
      }
    };
    dfs(sr, sc);
    return image;
  }
};
func floodFill(image [][]int, sr int, sc int, color int) [][]int {
  oc := image[sr][sc]
  m, n := len(image), len(image[0])
  dirs := []int{-1, 0, 1, 0, -1}
  var dfs func(i, j int)
  dfs = func(i, j int) {
    if i < 0 || i >= m || j < 0 || j >= n || image[i][j] != oc || image[i][j] == color {
      return
    }
    image[i][j] = color
    for k := 0; k < 4; k++ {
      dfs(i+dirs[k], j+dirs[k+1])
    }
  }
  dfs(sr, sc)
  return image
}
function floodFill(image: number[][], sr: number, sc: number, newColor: number): number[][] {
  const m = image.length;
  const n = image[0].length;
  const target = image[sr][sc];
  const dfs = (i: number, j: number) => {
    if (
      i < 0 ||
      i === m ||
      j < 0 ||
      j === n ||
      image[i][j] !== target ||
      image[i][j] === newColor
    ) {
      return;
    }
    image[i][j] = newColor;
    dfs(i + 1, j);
    dfs(i - 1, j);
    dfs(i, j + 1);
    dfs(i, j - 1);
  };
  dfs(sr, sc);
  return image;
}
impl Solution {
  fn dfs(image: &mut Vec<Vec<i32>>, sr: i32, sc: i32, new_color: i32, target: i32) {
    if sr < 0 || sr == (image.len() as i32) || sc < 0 || sc == (image[0].len() as i32) {
      return;
    }
    let sr = sr as usize;
    let sc = sc as usize;
    if sr < 0 || image[sr][sc] == new_color || image[sr][sc] != target {
      return;
    }
    image[sr][sc] = new_color;
    let sr = sr as i32;
    let sc = sc as i32;
    Self::dfs(image, sr + 1, sc, new_color, target);
    Self::dfs(image, sr - 1, sc, new_color, target);
    Self::dfs(image, sr, sc + 1, new_color, target);
    Self::dfs(image, sr, sc - 1, new_color, target);
  }
  pub fn flood_fill(image: Vec<Vec<i32>>, sr: i32, sc: i32, new_color: i32) -> Vec<Vec<i32>> {
    let target = image[sr as usize][sc as usize];
    Self::dfs(&mut image, sr, sc, new_color, target);
    image
  }
}

方法二

class Solution:
  def floodFill(
    self, image: List[List[int]], sr: int, sc: int, color: int
  ) -> List[List[int]]:
    if image[sr][sc] == color:
      return image
    q = deque([(sr, sc)])
    oc = image[sr][sc]
    image[sr][sc] = color
    dirs = (-1, 0, 1, 0, -1)
    while q:
      i, j = q.popleft()
      for a, b in pairwise(dirs):
        x, y = i + a, j + b
        if 0 <= x < len(image) and 0 <= y < len(image[0]) and image[x][y] == oc:
          q.append((x, y))
          image[x][y] = color
    return image
class Solution {
  public int[][] floodFill(int[][] image, int sr, int sc, int color) {
    if (image[sr][sc] == color) {
      return image;
    }
    Deque<int[]> q = new ArrayDeque<>();
    q.offer(new int[] {sr, sc});
    int oc = image[sr][sc];
    image[sr][sc] = color;
    int[] dirs = {-1, 0, 1, 0, -1};
    while (!q.isEmpty()) {
      int[] p = q.poll();
      int i = p[0], j = p[1];
      for (int k = 0; k < 4; ++k) {
        int x = i + dirs[k], y = j + dirs[k + 1];
        if (x >= 0 && x < image.length && y >= 0 && y < image[0].length
          && image[x][y] == oc) {
          q.offer(new int[] {x, y});
          image[x][y] = color;
        }
      }
    }
    return image;
  }
}
class Solution {
public:
  vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
    if (image[sr][sc] == color) return image;
    int oc = image[sr][sc];
    image[sr][sc] = color;
    queue<pair<int, int>> q;
    q.push({sr, sc});
    int dirs[5] = {-1, 0, 1, 0, -1};
    while (!q.empty()) {
      auto [a, b] = q.front();
      q.pop();
      for (int k = 0; k < 4; ++k) {
        int x = a + dirs[k];
        int y = b + dirs[k + 1];
        if (x >= 0 && x < image.size() && y >= 0 && y < image[0].size() && image[x][y] == oc) {
          q.push({x, y});
          image[x][y] = color;
        }
      }
    }
    return image;
  }
};
func floodFill(image [][]int, sr int, sc int, color int) [][]int {
  if image[sr][sc] == color {
    return image
  }
  oc := image[sr][sc]
  q := [][]int{[]int{sr, sc}}
  image[sr][sc] = color
  dirs := []int{-1, 0, 1, 0, -1}
  for len(q) > 0 {
    p := q[0]
    q = q[1:]
    for k := 0; k < 4; k++ {
      x, y := p[0]+dirs[k], p[1]+dirs[k+1]
      if x >= 0 && x < len(image) && y >= 0 && y < len(image[0]) && image[x][y] == oc {
        q = append(q, []int{x, y})
        image[x][y] = color
      }
    }
  }
  return image
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文