字节跳动笔试题之01数组联通域个数

输入一个只包含0和1的二维数组,上下左右和对角相邻的1组成一个区块,0不形成区块,求数组中的区块个数。

输入格式
第一行输入两个正整数N和M,N表示数组行数,M表示数组列数。

接下来N行,每行表示数组对应的一行,每行包含M个整数,整数之间用空格隔开。

输出格式
输出一个整数,表示数组中区块的个数。

数据范围
0 ≤ N, M, N∗M ≤ 10^6
输入样例:
3 3
0 1 0
1 0 0
1 0 1
输出样例:
2
样例解释
数组右下角的1单独构成一个区块,其他的3个1对角或上下相邻,构成另一个区块。

思路一: 二维数组进行 dfs

n,m = list(map(eval,input().split(' ')))
matrix = []
for _ in range(n):
    matrix += input().split(' '),
3 3
0 1 0
1 0 0
1 0 1
# 定义上下左右对角线的方位
dx = [-1, -1, -1, 0, 0, 1, 1, 1]
dy = [-1, 0, 1, -1, 1, -1, 0, 1]
res = 0

def dfs(i, j):
    matrix[i][j] = 0
    for k in range(len(dx)):
        x, y = i + dx[k], j + dy[k]
        if x>=0 and y>=0 and x<n and y<m and matrix[x][y] == '1':
            dfs(x, y)

for i in range(n):
    for j in range(m):
        if matrix[i][j] == '1':
            res += 1
            dfs(i, j)
print(res)
2

思路二:由于题目中的矩阵的长宽没有给定,在 C/C++ 语言中,最好是定义指定大小的数组,如果存在 10^6 * 10^6 的数组,会出现爆栈情况,所以这里有个小技巧,使用一维数组来保存题目的二位数组。

那么在二维数组的元素下标为 i,j 时,对应的一维数组元素下标应该是 i*m+j
一维数组的元素下标为 k 时,对应的二维数组元素下标应该是 k//m, k%m

n,m = list(map(eval,input().split(' ')))
matrix = []
for _ in range(n):
    matrix += input().split(' ')
3 3
1 1 1
0 1 0
1 0 1
matrix
['1', '1', '1', '0', '1', '0', '1', '0', '1']
res = 0

def dfs(x, y):
    matrix[x * m + y] = 0
    for i in range(-1, 2):
        for j in range(-1, 2):
            a, b = x+i, y+j
            if a >= 0 and a < n and b >= 0 and b < m and matrix[a * m + b] == '1':
                dfs(a, b)
                
for i in range(n):
    for j in range(m):
        if matrix[i * m + j] == '1':
            res += 1
            dfs(i, j)
print(res)
1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章