真的坑,自己想完全没想到,看了一些大神的博客写出来的。那个列表很坑,不能写在一起。
但作为一名小白还是很欣慰的。
'''
给定一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,计算岛屿的数量。
一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。
你可以假设网格的四个边均被水包围
'''
# 考虑这个题目,计算岛屿数量,也就是单独岛屿的数量,
# 两个以上的1 连在一起的算是一个岛屿,那么也就是只要找到单独一块的岛屿就行了,
# 这样就很好理解了!
lt1 = [
[1, 1, 0, 0, 0],
[0, 1, 0, 0, 1],
[0, 0, 0, 1, 1],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 1]
]
lt2 = [
[1, 1, 1, 1, 0],
[1, 1, 0, 1, 0],
[0, 0, 0, 1, 1],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 1]
]
class Solution:
def munIsLand(self, grid):
n = len(grid)
if n == 0:
return '地图为空'
m = len(grid[0])
if m == 0:
return '地图为空'
# 当找到岛屿的时候就把下面变量自+1
res = 0
# 开始遍历寻找第一个 1 ,(岛屿)
for i in range(n):
for j in range(m):
# 判断是不是一个岛屿
if grid[i][j] == 1:
res = res + 1
# 这个时候还要判断与它连接在一起的1,
# 毕竟一家人要整整齐齐的,所以递归寻找连在一起的所有岛屿,
# 同时需要注意的是,一个岛屿你只能遍历一次,
# 所以打个标识,让寻找到的岛屿变成0
self.change(grid, i, j)
return res
def change(self, grid, i, j):
grid[i][j] = 0
# 判断这个岛屿上下左右的方向
# 判断上方字符
if i > 0 and grid[i - 1][j] == 1:
self.change(grid, i - 1, j)
# 判断左方字符
if j > 0 and grid[i][j - 1] == 1:
self.change(grid, i, j - 1)
# 判断下方字符
if i < len(grid) - 1 and grid[i + 1][j] == 1:
self.change(grid, i + 1, j)
# 判断右方字符
if j < len(grid[0]) - 1 and grid[i][j + 1] == 1:
self.change(grid, i, j + 1)
ss = Solution()
print(ss.munIsLand(lt1))
print(ss.munIsLand(lt2))
- 关于密码锁问题
import collections
class Solution:
'''
算法思想:
这也是一道很有意思的题,其实本质就是个迷宫遍历的问题,只不过相邻位置不再是上下左右四个位置,
而是四位数字每个都加一减一,总共有八个相邻的位置。与经典BFS遍历迷宫解法唯一不同的就是找下一个位置的地方,
这里我们要遍历四位数字的每一位,然后分别加1减1,我们用j从-1遍历到1,遇到0跳过,也就是实现了加1减1的过程。
然后我们要计算要更新位上的数字,为了处理9加1变0,和0减1变9的情况,我们统一给该位数字加上个10,然后再加或减1,
最后再对10取余即可。
如果此时新生成的字符串等于target了,直接返回结果res,否则我们看如果该字符串不在死锁集合里,
且之前没有遍历过,那么加入队列queue中,之后将该字符串加入visited集合中即可。注意这里在while循环中,
由于要一层一层的往外扩展
'''
def openLock(self, deadends, target):
deadset = set(deadends)
if (target in deadset) or ("0000" in deadset):
return -1
# 之前没有遍历过加入队列之中
que = collections.deque()
que.append("0000")
# 然后在把他加入集合里面
visited = set(["0000"])
step = 0
# 这个要一层层的向外扩张
while que:
# 每次循环寻找次数都会+1
step += 1
# 计算每次循环时,队列中原书的个数
size = len(que)
# 在新的元素基础上开始遍历
for i in range(size):
# 依次取出 0 1 2 3 4 ... 赋值给point指针
point = que.popleft()
# 第二次循环,给每个滚轮上面操作
for j in range(4):
# 第三次循环,设置 +1, -1,让每个滚轮加+、减一
for k in range(-1, 2, 2):
# 程序执行到这里,point已经执行完毕了,也就是point就等于queue,这里是把point赋给newPoint
newPoint = [i for i in point]
# 让这个新赋值的队列中,给每个元素加减1操作,并且这里有-1-9,10-0的转换操作
newPoint[j] = chr((ord(newPoint[j]) - ord('0') + k) % 10 + ord('0'))
# 这里把列表里面['1','2','3','4']转换为'1234'
newPoint = "".join(newPoint)
# 判断这个字符串是不是目标字符串
if newPoint == target:
return step
# 如果这个字符串不再死锁或者集合字符串中, 就跳过这次循环
if (newPoint in deadset) or (newPoint in visited):
continue
# 把这个字符串加入到队列queue中
que.append(newPoint)
# 把这个字符串加入到集合中
visited.add(newPoint)
return -1
a = Solution()
ret = a.openLock('1515', '1523')
print(ret)