字節跳動筆試題之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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章