diff --git a/AlgorithmHomework10.md b/AlgorithmHomework10.md new file mode 100644 index 0000000..20badb5 --- /dev/null +++ b/AlgorithmHomework10.md @@ -0,0 +1,142 @@ +# Algorithm Homework 10 + +> 姓名:阙建明 +> +> 学号:1901213139 + +## 作业要求: + +Leetcode: 787, 934, 692 + +- ### Leetcode problem 787 + + > [K 站中转内最便宜的航班](https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/) + + - **算法思路:** + + 1. 用Djkstra算法求解单源最短路径的思路; + 2. 遇到大于限定跳数就跳出进行剪枝; + 3. 遇到目标节点就直接返回其最小开销,结束算法。 + + - **Leetcode提交结果:** + + ![image-20200507221022918](assets/1590673071603.png) + + - **代码:** + + ```python + class Solution(object): + def findCheapestPrice(self, n, flights, src, dst, K): + + # 构造图 + graph = collections.defaultdict(dict) + for u, v, w in flights: + graph[u][v] = w + + # 存储已确定最短路径的节点 + best = {} + + # 存储自src所指节点起始,到目的节点的的开销,跳数,和目的节点标号 + pq = [(0, 0, src)] + + # 用Djkstra求单源最短路径 + while pq: + cost, k, place = heapq.heappop(pq) + if k > K + 1 or cost > best.get((k, place), float('inf')): + continue + if place == dst: + return cost + + for nei, wt in graph[place].items(): + newCost = cost + wt + if newCost < best.get((k + 1, nei), float('inf')): + heapq.heappush(pq, (newCost, k + 1, nei)) + best[k + 1, nei] = newCost + return -1 + ``` + +- ### Leetcode problem 934 + + > [最短的桥](https://leetcode-cn.com/problems/shortest-bridge/) + + - **算法思路:** + 1. 首先用深度优先遍历找到两座岛屿,并随机选一座作为初始点source; + 2. 再用广度优先遍历的方法从source岛屿向target岛屿扩散 + - **Leetcode提交结果:** + + ![image-20200507222442113](assets/1590673939071.png) + + - **代码:** + + ```python + class Solution(object): + def shortestBridge(self, A): + R, C = len(A), len(A[0]) + + def neighbors(r, c): + for nr, nc in ((r-1,c),(r,c-1),(r+1,c),(r,c+1)): + if 0 <= nr < R and 0 <= nc < C: + yield nr, nc + + def get_components(): + done = set() + components = [] + for r, row in enumerate(A): + for c, val in enumerate(row): + if val and (r, c) not in done: + # Start dfs + stack = [(r, c)] + seen = {(r, c)} + while stack: + node = stack.pop() + for nei in neighbors(*node): + if A[nei[0]][nei[1]] and nei not in seen: + stack.append(nei) + seen.add(nei) + done |= seen + components.append(seen) + return components + + # 首先用深度优先遍历找到两座岛屿,并随机选一座作为初始点source + source, target = get_components() + + # 用广度优先遍历的方法从source岛屿向target岛屿扩散 + queue = collections.deque([(node, 0) for node in source]) + done = set(source) + while queue: + node, d = queue.popleft() + if node in target: return d-1 + for nei in neighbors(*node): + if nei not in done: + queue.append((nei, d+1)) + done.add(nei) + + ``` + +- ### Leetcode problem 692 + + > [前K个高频单词](https://leetcode-cn.com/problems/top-k-frequent-words/) + + - **算法思路:** + 1. 首先调用collections.Counter统计单词出现的词频; + 2. 然后根据词频来从大到小进行排序; + 3. 最后取出前K个就是结果。 + - **Leetcode提交结果:** + + ![image-20200507225110291](assets/1590674294326.png) + + - **代码:** + + ```python + class Solution(object): + def topKFrequent(self, words, k): + # 使用python的类库计算单词的词频 + count = collections.Counter(words) + candidates = list(count.keys()) + + # 根据词频排序 + candidates.sort(key=lambda w: (-count[w], w)) + return candidates[:k] + ``` + + \ No newline at end of file diff --git a/assets/1590673071603.png b/assets/1590673071603.png new file mode 100644 index 0000000..efa8a73 Binary files /dev/null and b/assets/1590673071603.png differ diff --git a/assets/1590673939071.png b/assets/1590673939071.png new file mode 100644 index 0000000..c52940f Binary files /dev/null and b/assets/1590673939071.png differ diff --git a/assets/1590674294326.png b/assets/1590674294326.png new file mode 100644 index 0000000..d4e2c8b Binary files /dev/null and b/assets/1590674294326.png differ