【多源广搜】【DFS】地图中的最高点/判断二分图+浅谈Python中数组的浅拷贝和深拷贝
地图中的最高点
多源广搜的重点:确保能正确判断两个源点发生交会
判断二分图
DFS的trick:Python3 用nonlocal
关键字修饰flag,可以标记是否为有效二分图
用all
来判断
Python中数组的浅拷贝和深拷贝:
在Python中,数组的拷贝操作可以分为浅拷贝和深拷贝两种方式:
浅拷贝(Shallow Copy):
浅拷贝创建了一个新的对象,该对象是源对象的一个副本。但是,新对象中的元素仍然是源对象元素的引用。换句话说,新对象只是源对象的一个浅层副本,其中的元素仍然指向相同的内存地址。
在Python中,可以使用切片操作或copy()
函数执行浅拷贝。例如:
original_list = [1, 2, 3, [4, 5]]
shallow_copy = original_list[:] # 使用切片操作进行浅拷贝
对于浅拷贝,当修改源对象的可变元素时,新对象也会受到影响,因为它们共享相同的引用。但是,如果修改源对象的不可变元素,例如整数或字符串,新对象不会受到影响。
深拷贝(Deep Copy):
深拷贝创建了一个全新的对象,并且递归地复制源对象及其所有嵌套对象。这意味着新对象和源对象是完全独立的,对一个对象的修改不会影响另一个对象。
在Python中,可以使用copy.deepcopy()
函数执行深拷贝。例如:
import copy
original_list = [1, 2, 3, [4, 5]]
deep_copy = copy.deepcopy(original_list) # 执行深拷贝
对于深拷贝,即使修改源对象的可变元素,新对象也不会受到影响,因为它们具有不同的内存地址。
需要注意的是,深拷贝可能会更耗费内存和处理时间,特别是当源对象包含大量嵌套对象时。因此,只有在需要真正独立的副本时才需要执行深拷贝。
总结:
- 浅拷贝创建一个新对象,但是其中的元素仍然是源对象元素的引用。
- 深拷贝创建一个全新的对象,并递归地复制源对象及其所有嵌套对象。
- 对于浅拷贝,修改源对象的可变元素会影响新对象,而不可变元素不会受到影响。
- 对于深拷贝,无论修改源对象的哪个元素,新对象都不会受到影响。
地图中的最高点:
class Solution:
def highestPeak(self, isWater: List[List[int]]) -> List[List[int]]:
water_tiles = []
m = len(isWater)
n = len(isWater[0])
for i in range(m):
for j in range(n):
if isWater[i][j] == 1: # Check for water, not 0
water_tiles.append((i, j))
height = [[-1] * n for _ in range(m)] # Initialize height grid
queue = deque()
for tile in water_tiles:
x, y = tile
height[x][y] = 0 # Set water tiles to height 0
queue.append(tile)
while queue:
x, y = queue.popleft()
for dx, dy in [(-1, 0), (1, 0), (0, 1), (0, -1)]:
x_ = x + dx
y_ = y + dy
if 0 <= x_ < m and 0 <= y_ < n and height[x_][y_] == -1:
height[x_][y_] = height[x][y] + 1
queue.append((x_, y_))
return height
错误的写法的反思——没有正确判断源点的交会
- 在原始代码中,错误地将水域的方格识别为值为0的方格。在修正后的代码中,我们检查值为1来识别水域方格。
- height 网格被初始化为
isWater
的浅拷贝,这将导致修改原始的isWater
列表。在修正后的代码中,height
被初始化为一个与isWater
相同尺寸的新网格,所有值都设置为-1。 - 在循环中,
source
变量是不必要的。修正后的代码直接使用坐标x
和y
。 - 循环中的 x_ 和 y_ 计算错误。正确的计算方法是将
dx
和dy
添加到x
和y
上。 - 条件语句中的条件是检查
height[x_][y_] == 0
,这只允许遍历高度为0的单元格。在修正后的代码中,条件是height[x_][y_] == -1
,允许遍历未访问过的单元格。
class Solution:
def highestPeak(self, isWater: List[List[int]]) -> List[List[int]]:
water_tiles = []
m = len(isWater)
n = len(isWater[0])
for i in range(m):
for j in range(n):
if isWater[i][j] == 0:
water_tiles.append((i, j))
isWater[i][j] = 0
height = isWater[:]
queue = deque()
queue.extend(water_tiles)
while queue:
size = len(queue)
for i in range(size):
source = queue.popleft()
for dx, dy in [(-1, 0), (1, 0), (0, 1), (0, -1)]:
x, y = source
x_ = x - dx
y_ = y - dy
if (0 <= x_ < m) and (0 <= y_ < n) and height[x_][y_] == 0:
height[x_][y_] = height[x][y] + 1
queue.append((x_, y_))
return height
判断二分图
class Solution:
def isBipartite(self, graph: List[List[int]]) -> bool:
colored = {}
def dfs(v, color):
if v in colored:
return colored[v] == color
colored[v] = color
next_color = "B" if color == "R" else "R"
return all(dfs(neighbour, next_color) for neighbour in graph[v])
for vertex in range(len(graph)):
if vertex not in colored:
if not dfs(vertex, "R"):
return False
return True