left is left pointer, i is right pointer 外循环为扩张,内循环为收缩。收缩条件为固定字符种数(必须固定或者少于k)或者(以及)固定字符频数。若字符种数不固定,要试1-26种字符,才能单调,详见L395
求最短串
Python代码:
1 2 3 4 5 6 7 8
deftwo_pointers(self, nums): for i inrange(len(nums)): <calculate condition such as char_to_count> while <meets condition>: res = min(res, i - left + 1) <求最短子列> <anti-calculate condition such as char_to_count> left += 1 return <result>
求最长串
Python代码:
1 2 3 4 5 6 7 8
deftwo_pointers(self, nums): for i inrange(len(nums)): <calculate condition such as char_to_count> while <does not meet condition>: <anti-calculate condition such as char_to_count> left += 1 res = max(res, i - left + 1) <求最短子列> return <result>
Given an array of positive integers nums and a positive integer target, return the minimal length of a contiguous subarray[nums<sub>l</sub>, nums<sub>l+1</sub>, ..., nums<sub>r-1</sub>, nums<sub>r</sub>] of which the sum is greater than or equal to target. If there is no such subarray, return 0 instead.
Example 1:
Input: target = 7, nums = [2,3,1,2,4,3] Output: 2 Explanation: The subarray [4,3] has the minimal length under the problem constraint.
For a undirected graph with tree characteristics, we can choose any node as the root. The result graph is then a rooted tree. Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs). Given such a graph, write a function to find all the MHTs and return a list of their root labels.
Format The graph contains n nodes which are labeled from 0 to n - 1. You will be given the number n and a list of undirected edges (each edge is a pair of labels).
You can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges.
Example 1:
Given n = 4, edges = [[1, 0], [1, 2], [1, 3]]
0
|
1
/ \
2 3
return [1]
Example 2:
Given n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
0 1 2
\ | /
3
|
4
|
5
return [3, 4]
Note:
(1) According to the definition of tree on Wikipedia): “a tree is an undirected graph in which any two vertices are connected by exactly one path. In other words, any connected graph without simple cycles is a tree.”
(2) The height of a rooted tree is the number of edges on the longest downward path between the root and a leaf.
deffindMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]: ifnot edges: return [0] # remember graph = collections.defaultdict(list) in_degree = [0] * n for li in edges: graph[li[0]].append(li[1]) graph[li[1]].append(li[0]) in_degree[li[0]] += 1 in_degree[li[1]] += 1 queue = collections.deque([i for i inrange(len(in_degree)) if in_degree[i] == 1]) res = list(queue) # remember while queue: for _ inrange(len(queue)): node = queue.popleft() for neighbor in graph[node]: in_degree[neighbor] -= 1 if in_degree[neighbor] == 1: queue.append(neighbor) if queue: # remember res = list(queue) return res
Given an integer matrix, find the length of the longest increasing path.
From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed).
Example 1:
nums = [
[9,9,4],
[6,6,8],
[2,1,1]
]
Return 4 The longest increasing path is [1, 2, 6, 9].
Example 2:
nums = [
[3,4,5],
[3,2,6],
[2,2,1]
]
Return 4 The longest increasing path is [3, 4, 5, 6]. Moving diagonally is not allowed.
deflongestIncreasingPath(self, matrix: List[List[int]]) -> int: ary = [] for i inrange(len(matrix)): for j inrange(len(matrix[0])): ary.append((matrix[i][j], i, j)) ary.sort() dp = [[1for _ inrange(len(matrix[0]))] for _ inrange(len(matrix))] for val, _x, _y in ary: for _dx, _dy in OFFSETS: x, y = _x + _dx, _y + _dy if x < 0or x >= len(matrix) or y < 0or y >= len(matrix[0]): continue if matrix[x][y] > matrix[_x][_y]: dp[x][y] = max(dp[x][y], dp[_x][_y] + 1) returnmax(map(max, dp))
You are given an m x n grid grid of values 0, 1, or 2, where:
each 0 marks an empty land that you can pass by freely,
each 1 marks a building that you cannot pass through, and each 2 marks an obstacle that you cannot pass through.
You want to build a house on an empty land that reaches all buildings in the shortest total travel distance. You can only move up, down, left, and right.
Return the shortest travel distance for such a house. If it is not possible to build such a house according to the above rules, return -1.
The total travel distance is the sum of the distances between the houses of the friends and the meeting point.
The distance is calculated using Manhattan Distance, where distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|.
Example 1:
Input: grid = [[1,0,2,0,1],[0,0,0,0,0],[0,0,1,0,0]] Output: 7 Explanation: Given three buildings at (0,0), (0,4), (2,2), and an obstacle at (0,2). The point (1,2) is an ideal empty land to build a house, as the total travel distance of 3+3+1=7 is minimal. So return 7.
Example 2:
Input: grid = [[1,0]] Output: 1
Example 3:
Input: grid = [[1]] Output: -1
Constraints:m == grid.length n == grid[i].length1 <= m, n <= 50 grid[i][j] is either 0, 1, or 2.
There will be at least one building in the grid.
题目大意:
找到所有大厦最短距离的点,这个点不能是大厦也不能是障碍
解题思路:
一开始觉得类似于LeetCode 296 Best Meeting Point,但由于有障碍,所以不能用贪婪法。最值考虑用BFS。属于对所有节点BFS。类似于LeetCode 200 Number of Islands, 从每一栋大厦开始做BFS,计算每个点到此大厦距离。然后对累计到这个点的总距离矩阵dis中。最后求距离矩阵的最小值。
OFFSETS = [(-1, 0), (1, 0), (0, -1), (0, 1)] defshortestDistance(self, grid: List[List[int]]) -> int: dis = [[0for _ inrange(len(grid[0]))] for _ inrange(len(grid))] house_count = [[0for _ inrange(len(grid[0]))] for _ inrange(len(grid))] total_houses = 0 for i inrange(len(grid)): for j inrange(len(grid[0])): if grid[i][j] == 1: self.bfs(grid, i, j, dis, house_count) total_houses += 1 min_dis = float('inf') # remember for i inrange(len(dis)): for j inrange(len(dis[0])): if dis[i][j] > 0and house_count[i][j] == total_houses: min_dis = min(min_dis, dis[i][j]) return -1if min_dis == float('inf') else min_dis # remember
defbfs(self, grid, start_x, start_y, dis, house_count): h = len(grid) w = len(grid[0]) # remember otherwise TLE queue = collections.deque([(start_x, start_y, 0)]) visited = [[Falsefor _ inrange(len(grid[0]))] for _ inrange(len(grid))] visited[start_x][start_y] = True while queue: node = queue.popleft() for _dx, _dy in OFFSETS: x, y = node[0] + _dx, node[1] + _dy if x < 0or x >= h or y < 0or y >= w or grid[x][y] != 0or visited[x][y]: continue queue.append((x, y, node[2] + 1)) visited[x][y] = True dis[x][y] += node[2] + 1 house_count[x][y] += 1