Leetcode No. 692, 787, 934作业报告
No. 692
- 思路
方法一:
直接使用sorted函数,重写cmp的排序算法,对整个序列进行排序,取前k个元素
注意的点:
1. python中的cmp方法需要返回值必须为 [1,-1,0]
2. 当不符合排序条件需要调整的时候返回1,符合的话返回-1,相等的话返回0,后两者不需要调整顺序
方法二:
定义一个Word类,重写def __lt__(self, other)方法
然后使用heapq.heappush(heap, Word(word, fre))和heapq.heappop(heap)方法对heap进行排序
采用与题目相反的排序,将前n-k个都pop掉,剩下的k个通过reverse获得最终答案
- 代码
方法一:
class Solution(object):
def myCmp(self, a, b):
# python中的cmp方法需要返回值必须为 [1,-1,0]
# 当不符合排序条件需要调整的时候返回1,符合的话返回-1,相等的话返回0,后两者不需要调整顺序
if a[0]==b[0]:
#print(a[1], b[1], a[1]>b[1])
if a[1]>b[1]:
return 1
return -1
elif a[0]<b[0]:
return 1
return -1
def topKFrequent(self, words, k):
"""
:type words: List[str]
:type k: int
:rtype: List[str]
"""
count = collections.Counter(words)
items = [(val, key) for key, val in count.items()]
itemsSorted = sorted(items, key = functools.cmp_to_key(self.myCmp))[:k]
result = [(item[1]) for item in itemsSorted]
return result
方法二:
class Word:
def __init__(self, word, fre):
self.word = word
self.fre = fre
def __lt__(self, other):
if self.fre != other.fre:
return self.fre < other.fre
return self.word > other.word
class Solution:
def topKFrequent(self, words: List[str], k: int) -> List[str]:
cnt = collections.Counter(words)
heap = []
for word, fre in cnt.items():
heapq.heappush(heap, Word(word, fre))
if len(heap) > k:
heapq.heappop(heap)
heap.sort(reverse=True)
return [x.word for x in heap]
- 作业截图
方法一:
方法二:
No. 787
- 思路
使用二维数组进行动态规划,定义dp[N][k]为在最多k个中转站的限制条件之下从src到达N的最短距离
动态规划,在k个中转限制下飞到目的地的最便宜价格等于
在k-1个中转限制下飞到目的地的最便宜价格或者利用额外一个中转地到目的地 的最低价格
因此状态转移方程为:dp[v][k] = min({dp[v][k - 1], dp[v][k], dp[u][k - 1] + w})
- 代码
class Solution(object):
def findCheapestPrice(self, N, flights, src, dst, K):
dp = [[float('inf')] * (K + 1) for _ in range(0, N)]
K = min(K, N - 2);
# 最基本的直接飞到目的地
dp[src][0] = 0
# 对dp二维数组进行初始化
for flight in flights:
start = flight[0]
end = flight[1]
price = flight[2]
if (start == src) :
dp[end][0] = min(dp[end][0], price)
for k in range(1, K + 1):
for flight in flights:
u = flight[0];
v = flight[1];
w = flight[2];
# 动态规划,在k个中转限制下飞到目的地的最便宜价格等于
# 在k-1个中转限制下飞到目的地的最便宜价格或者利用额外一个中转地到目的地 的最低价格
dp[v][k] = min({dp[v][k - 1], dp[v][k], dp[u][k - 1] + w})
return -1 if dp[dst][K] == float('inf') else dp[dst][K]
- 作业截图
No. 934
- 思路
采用dfs+bfs
因为存在两个不相连的岛,所以需要先用dfs,将其中一个岛的所有1找到并标识为2(与0和另一个岛的1区分开来)
将遍历过的2存入一个队列中
然后以该队列中的所有点为起点进行bfs遍历,直到遇到1为止则中止bfs遍历
需要注意的是,遍历的时候不要出界;遍历过的点需要表示为2(表示已经遍历过)
- 代码
class Solution:
def __init__(self):
# 记录访问过的位置
self.visited = []
# 深度搜索,目的在与找到第一座岛并将其标记2这样可以不跟第二个冲突
def dfs(self, A, i, j):
# 记录岛的位置
self.visited.append((i, j))
A[i][j] = 2
# 遍历四个方向
for k, l in [(-1, 0), (0, 1), (1, 0), (0, -1)]:
r = k + i
c = l + j
# 判断移动后的合理性
if r < 0 or r >= len(A) or c < 0 or c >= len(A[0]):
continue
# 如果是0或者标记过的2则继续
if A[r][c] == 0 or A[r][c] == 2:
continue
# 同一个岛的进行递归
self.dfs(A, r, c)
def shortestBridge(self, A):
maxr, maxc = len(A), len(A[0])
for i in range(maxr):
for j in range(maxc):
# 碰到第一个的时候开始深度搜索来找到第一个岛
if A[i][j] == 1:
self.dfs(A, i, j)
# !!!注意这里只需要找到第一个岛,深度搜索后需要跳出两层循环,用for...else...结构
break
else:
continue
break
# step记录广度搜索的宽度
step = 0
# vist有的时候
while self.visited:
# 记录这次需要进行搜索的个数,这么做是因为后面搜索过程中会再添加
vl = len(self.visited)
# 将依次搜索本次step广度的各个节点
for v in range(vl):
i,j = self.visited.pop(0)
for k,l in [(-1, 0), (0, 1), (1, 0), (0, -1)]:
r = k + i
c = l + j
if r < 0 or r >= len(A) or c < 0 or c >= len(A[0]):
continue
if A[r][c] == 2:
continue
# step广度是由浅岛深,任何依次找到下一个岛即可返回step了
if A[r][c] == 1:
return step
# 否则经过0的话需要将位置标记为2,代表搜索过了,并且需要加入vist,
# 因为下一个广度也需要搜索其周围
A[r][c] = 2
self.visited.append((r, c))
step += 1
# 都没有则返回最大的广度
return step
- 作业截图