【LeetCode每日一题】——面试题 08.10. 颜色填充

一【题目类别】

  • 广度优先搜索

二【题目难度】

  • 简单

三【题目编号】

  • 面试题 08.10. 颜色填充

四【题目描述】

  • 编写函数,实现许多图片编辑软件都支持的「颜色填充」功能。
  • 待填充的图像用二维数组 image 表示,元素为初始颜色值。初始坐标点的行坐标为 sr 列坐标为 sc。需要填充的新颜色为 newColor
  • 「周围区域」是指颜色相同且在上、下、左、右四个方向上存在相连情况的若干元素。
  • 请用新颜色填充初始坐标点的周围区域,并返回填充后的图像。

五【题目示例】

  • 示例:
    • 输入:
      • 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 ,因为它不属于初始坐标点的周围区域。

六【题目提示】

  • imageimage[0] 的长度均在范围 [1, 50] 内。
  • 初始坐标点 (sr,sc) 满足 0 <= sr < image.length0 <= sc < image[0].length
  • image[i][j]newColor 表示的颜色值在范围 [0, 65535] 内。

七【解题思路】

  • 这道题的思路还是比较经典的,使用广度优先算法去寻找与目标点颜色相同的点,然后对其赋值即可,只不过有些细节需要注意
    • 要正确的设置上下左右四个方向
    • 如果目标点颜色和目标颜色相同,可以直接返回传入的二维数组
    • 边界条件不能判断出错
    • 正确的赋值,不要搞混颜色

八【时间频度】

  • 时间复杂度: O ( n × m ) O(n × m) O(n×m),其中 n n n m m m分别为传入的二维数组的行数和列数
  • 空间复杂度: O ( n × m ) O(n × m) O(n×m),其中 n n n m m m分别为传入的二维数组的行数和列数

九【代码实现】

  1. Java语言版
class Solution {
    
    // 初始化上下左右四个方向
    int[] dx = {1, 0, 0, -1};
    int[] dy = {0, 1, -1, 0};

    public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {

        // 获取原始颜色
        int originColor = image[sr][sc];

        // 如果当前颜色和目标颜色相同直接返回
        if (originColor == newColor) {
            return image;
        }

        // 获取初始信息
        int row = image.length;
        int col = image[0].length;

        // 初始化队列
        Queue<int[]> queue = new LinkedList<int[]>();
        queue.offer(new int[]{sr, sc});
        image[sr][sc] = newColor;

        // 开始使用广度优先搜索进行颜色填充
        while (!queue.isEmpty()) {
            int[] pos = queue.poll();
            int x = pos[0];
            int y = pos[1];
            for (int i = 0; i < 4; i++) {
                int newX = x + dx[i];
                int newY = y + dy[i];
                if (newX >= 0 && newX < row && newY >= 0 && newY < col && image[newX][newY] == originColor) {
                    queue.offer(new int[]{newX, newY});
                    image[newX][newY] = newColor;
                }
            }
        }
        
        // 返回结果
        return image;
    }
}
  1. Python语言版
class Solution:
    def floodFill(self, image: List[List[int]], sr: int, sc: int, newColor: int) -> List[List[int]]:
        # 保存初始颜色
        originColor = image[sr][sc]
        
        # 如果当前颜色和目标颜色相同,直接返回
        if originColor == newColor:
            return image

        # 获取初始值
        row = len(image)
        col = len(image[0])

        # 初始化队列
        queue = collections.deque([(sr, sc)])
        image[sr][sc] = newColor

        # 使用广度优先算法填充颜色
        while queue:
            x, y = queue.popleft()
            for new_x, new_y in [(x - 1, y), (x + 1, y), (x, y -1), (x, y + 1)]:
                if new_x >= 0 and new_x < row and new_y >= 0 and new_y < col and image[new_x][new_y] == originColor:
                    queue.append((new_x, new_y))
                    image[new_x][new_y] = newColor
        
        # 返回结果
        return image
  1. C语言版
// 设置上下左右四个方向
const int dx[4] = {1, 0, 0, -1};
const int dy[4] = {0, 1, -1, 0};

int** floodFill(int** image, int imageSize, int* imageColSize, int sr, int sc, int newColor, int* returnSize, int** returnColumnSizes){

    // 初始化值
    int row = imageSize;
    int col = imageColSize[0];
    int n = row * col;

    // 设置返回数据的行和列数
    *returnSize = row;
    *returnColumnSizes = (int *)malloc(row * sizeof(int));
    for (int i = 0; i < row; i++)
    {
        (*returnColumnSizes)[i] = col;
    }

    // 如果起始点已经是新颜色,直接返回
    if (newColor == image[sr][sc])
    {
        return image;
    }

    // 初始化队列
    int** queue = (int **)malloc(sizeof(int*) * n);
    for (int i = 0; i < n; i++)
    {
        queue[i] = (int *)malloc(sizeof(int) * 2);       
    }
    int rear = 0;
    int front = 0;

    // 初始坐标点入队列
    queue[rear][0] = sr;
    queue[rear++][1] = sc;

    // 保存初始颜色
    int originalColor = image[sr][sc];

    // 初始坐标点填充新颜色
    image[sr][sc] = newColor;

    // 开始使用广度优先算法进行颜色填充
    while (front != rear)
    {
        int x = queue[front][0];
        int y = queue[front++][1];
        
        for (int i = 0; i < 4; i++)
        {
            int newX = x + dx[i];
            int newY = y + dy[i];
            if (newX >= 0 && newX < row && newY >= 0 && newY < col && image[newX][newY] == originalColor)
            {
                queue[rear][0] = newX;
                queue[rear++][1] = newY;
                image[newX][newY] = newColor;
            }
        }
    }
    
    // 释放队列内存
    for (int i = 0; i < n; i++) {
        free(queue[i]);
    }
    free(queue);

    return image;

}

十【提交结果】

  1. Java语言版
    在这里插入图片描述

  2. Python语言版
    在这里插入图片描述

  3. C语言版
    在这里插入图片描述

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IronmanJay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值