LeetCode 533----Lonely Pixel II

问题描述

Given a picture consisting of black and white pixels, and a positive integer N, find the number of black pixels located at some specific row R and column C that align with all the following rules:

  1. Row R and column C both contain exactly N black pixels.
  2. For all rows that have a black pixel at column C, they should be exactly the same as row R

The picture is represented by a 2D char array consisting of 'B' and 'W', which means black and white pixels respectively.

Example:
Input:                                        
    [['W', 'B', 'W', 'B', 'B', 'W'],    
     ['W', 'B', 'W', 'B', 'B', 'W'],    
     ['W', 'B', 'W', 'B', 'B', 'W'],    
     ['W', 'W', 'B', 'W', 'B', 'W']] 

N = 3
Output: 6  
Explanation: All the bold 'B' are the black pixels we need (all 'B's at column 1 and 3).  
            0    1    2    3    4    5         column index                                            
    0    [['W', 'B', 'W', 'B', 'B', 'W'],    
    1     ['W', 'B', 'W', 'B', 'B', 'W'],    
    2     ['W', 'B', 'W', 'B', 'B', 'W'],    
    3     ['W', 'W', 'B', 'W', 'B', 'W']]    
row index

Take 'B' at row R = 0 and column C = 1 as an example:
Rule 1, row R = 0 and column C = 1 both have exactly N = 3 black pixels. 
Rule 2, the rows have black pixel at column C = 1 are row 0, row 1 and row 2. They are exactly the same as row R = 0.



Note:

The range of width and height of the input 2D array is [1,200].

算法分析

先遍历一次二维表,统计各行各列 'B' pixel 的个数。 然后构造一个HashMap<String,Integer),对于那些 'B' 的个数有 N 个的行,将该行的 'WB' 序列当做一个字符串,统计这样的序列有多少。最后再对那些 'B' 的个数有 N 个的行,如果 HashMap 中该行的字符序列有 N 个,那么遍历该行所有的 'B' 所在的列,如果这一列有 N 个 'B',那么这一列的 N 个 'B' 就都是符合要求的 pixel了。 为了快速找到一行中的 'B' 所在的列,构造一个二维数组 int[][] rowIndexex=new int[rows][N],rowIndexes[i][j] 用于记录第 i 行第 j 个 'B' 所在的列数。

Java 算法实现:

public class Solution {
    public int findBlackPixel(char[][] picture, int N) {
        int rows=picture.length;
        int cols=picture[0].length;
        int []row=new int[rows];
        int []col=new int[cols];
        int [][]rowIndexes=new int[rows][N];//rowIndexes[i][j] 用于记录第 i 行第 j 个 'B' 所在的列数。
        for(int i=0;i<rows;i++){
            for(int j=0;j<cols;j++){
                if(picture[i][j]=='B'){
                    if(row[i]!=-1&&row[i]!=N){
                        rowIndexes[i][row[i]]=j;//当前考察的'B'是第i行的第row[i]个'B'(从0开始计数),其所在列为 j 。
                        row[i]++;
                    }
                    else if(row[i]==N){// 第i行中的'B'的个数超过了N个,就将row[i]置为-1,以后就不用考虑该行了
                        row[i]=-1;
                    }
                    col[j]++;
                }
            }
        }
        Map<String, Integer>map=new HashMap<>();
        for(int i=0;i<rows;i++){
            String str=new String(picture[i]);//将这一行的'WB'序列当做一个字符串
            if(map.containsKey(str)){//统计这中序列的个数,便于后面快速判断这一行是否符合要求(即有N个行的序列是这个序列)
                int value=map.get(str)+1;
                map.put(str, value);
            }
            else{
                map.put(str, 1);
            }
        }
        
        int ans=0;
        
        for(int i=0;i<rows;i++){
            if(row[i]==N){
                String key=new String(picture[i]);
                if(map.get(key)==N){//对于那些row[i]==N的行,其序列数目也为N,那么这一行上的'B'可能符合要求,下面进一步判断
                    for(int j=0;j<N;j++){
                        int jCol=rowIndexes[i][j];//jCol为第i行的'B'所在的列
                        if(col[jCol]==N){//这一列符合要求,那么这一列的N个'B'就都符合要求
                            ans+=N;
                            col[jCol]=-2;//后面跟这一列关联的行就不需要再进行重复计算了
                        }
                        else if(col[jCol]==-2){//说明与该行关联的含'B'的列之前已经在前面的行中进行统计过了,那么这一行就不必再统计了,直接退出本行的统计就可以了,提高算法时间效率
                            break;
                        }
                    }
                }
            }
        }
        return ans;
    }
}

转载于:https://www.cnblogs.com/dongling/p/6509348.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值