def numIslands(grid: List[List[str]]) -> int:
# dfs set all of the land linked to the current land (if it is land) to 'already seen' (#)
# dfs does if by recursion. it stops if current grid is water or border
def dfs(grid, i, j):
if i<0 or j<0 or i>=len(grid) or j>=len(grid[0]) or grid[i][j] != '1':
return
grid[i][j] = '#'
dfs(grid, i+1, j)
dfs(grid, i-1, j)
dfs(grid, i, j+1)
dfs(grid, i, j-1)
# if grid is emtpy then there is no island
if not grid:
return 0
island_count = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
# if a grid value is 1 (land), add 1 to the island counter and set all of the linked lands to already counter (#)
if grid[i][j] == '1':
dfs(grid, i, j) # set all related land (and this one) to 'already seen'
island_count += 1 # update the island counter
return island_count