Competition address:
https://leetcode-cn.com/contest/weekly-contest-240
First of all, I wish you a happy mother's Day! Let's look at the question
Question 1
subject
Enter a two-dimensional integer array logs, where
l
o
g
s
[
i
]
=
[
b
i
r
t
h
i
,
d
e
a
t
h
i
]
logs[i] = [birth_i, death_i]
logs[i]=[birthi, deathi] indicates the year of birth and death of the ith person. The population of year x is defined as the number of people alive during that year. The population of the ith person included in year x needs to meet:
x
∈
[
b
i
r
t
h
i
,
d
e
a
t
h
i
−
1
]
x\in [birthi, deathi-1]
x ∈ [birthi,deathi − 1].
Returns the most populous and earliest year.
Input: logs = [[1950,1961],[1960,1971],[1970,1981]] Output: 1960 Explanation: The largest population is 2, which occurred in 1960 and 1970 respectively. The earliest year is 1960.
analysis
Use an array with a length of 100 to save the number of people in each year respectively. Finally, use index() to return the year when the maximum value first appears.
answer
class Solution: def maximumPopulation(self, logs: List[List[int]]) -> int: import numpy as np rst = np.array([0] * 100) for l, r in logs: l, r = l - 1950, r - 1950 rst[l: r] += 1 return rst.tolist().index(max(rst)) + 1950
Question 2
subject
Given two non incremental integer arrays nums1 and nums2, the array subscripts are counted from 0. Subscript pairs (i, j) satisfy both i ≤ j i\leq j i ≤ j and n u m s 1 [ i ] ≤ n u m s 2 [ j ] nums1[i]\leq nums2[j] nums1[i] ≤ nums2[j], it is called an effective subscript pair, and the distance of the subscript pair is j − i j-i j−i. Returns the maximum distance among all valid subscript pairs (i, j). If there is no valid subscript pair, returns 0.
Input: nums1 = [55,30,5,4,2], nums2 = [100,20,10,10,5] Output: 2 Explanation: valid subscript pairs are (0,0), (2,2), (2,3), (2,4), (3,3), (3,4) and (4,4) . The maximum distance is 2, corresponding to the subscript pair (2,4) .
analysis
If you want the most j − i j-i j − i, push j backward as far as possible when i is fixed
nums1 = [55,30,5,4,2]
nums2 = [70,65,45,20,5]
If i=0, the maximum j is 1
If i=1, the maximum j is 2
If i=2, the maximum j is 4
Through observation, it is easy to find that every time i advances 1 bit backward, because the array is not incremented, n u m s 1 [ i ] ≥ n u m s 1 [ i + 1 ] nums1[i]\geq nums1[i+1] nums1[i] ≥ nums1[i+1], so j can continue to push backward, i.e j i ≥ j i + 1 j_i \geq j_{i+1} ji ≥ ji+1, when traversing i, j only needs to push backward all the time, so it can i , j i,j i. j is placed at the beginning of the array, I is pushed back one bit at a time, and the value of j is updated. Each element in the array will be traversed only once, so the solution is O ( n ) O(n) O(n).
Finally, it should be noted that there may not be such a number pair.
answer
class Solution: def maxDistance(self, nums1: List[int], nums2: List[int]) -> int: i, j, rst = 0, 0, 0 m = -float('inf') l1, l2 = len(nums1), len(nums2) # Push i backward 1 while i < l1: # The corresponding will push j backward while j < l2 and nums2[j] >= nums1[i]: j += 1 m = max(m, j - i - 1) i += 1 # m ≤ 0 indicates that there is no valid subscript pair return max(m, 0)
Question 3
subject
The minimum product of an array is defined as the sum of the minimum value in the array multiplied by the array elements. Given a positive integer array nums, returns the maximum value of the minimum product of any non empty sub array nums. The answer is right 1 0 9 + 7 10^9+7 109 + 7. Subarray is a continuous part of an array.
Examples
Input: nums = [1,2,3,2] Output: 14 Explanation: the maximum value of the minimum product is determined by the subarray [2,3,2] (The minimum value is 2). 2 * (2+3+2) = 2 * 7 = 14 .
analysis
- In order to calculate the sum of each subarray faster, calculate the prefix sum first.
- The minimum product of sub numbers is related to the minimum value (PIT), so it is necessary to determine the influence range of each "pit". For example, in the array [3, 5, 6, 1, 3, 2, 5], any sub array passing through 1 is affected by 1, while 2 can only affect 3 on the left and 5 on the right, and then 1 on the left. Therefore, it is necessary to determine the range boundary that each number can affect, The left boundary is actually the position of the first number on the left of each number. The left boundary of each number in the above array is [- 1, 0, 1, - 1, 3, 3, 5], where - 1 indicates that there are no smaller elements on the left of the number, so it can affect the leftmost. Accordingly, the right boundary is [3, 3, 3, 7, 5, 7, 7], and 7 indicates that there are no smaller elements on the right of the number, so it can affect the rightmost.
- The left boundary and right boundary can be solved by monotone stack. When the newly added element is smaller, the previous element finds the right boundary. On the contrary, it needs to enter the stack and wait for the emergence of the right boundary.
- In fact, the solution of the left boundary and the right boundary can be completed at one time. Consider the solution process of the right boundary: when x is added from left to right, the larger number on the left of X cannot be the left boundary of X (because x is smaller), while the smaller number on the left of X must be retained in the monotone stack. Therefore, the information in the monotone stack is also sufficient to calculate the left boundary. When x is put into the stack, the top element of the stack (except x) is the left boundary of X.
- It should be noted that if the number x equal to the top of the stack appears on the right, x will not be regarded as the right boundary, which will affect the search for the left boundary of X. therefore, it can be specified that the right boundary is less than or equal to the number, and the left boundary is strictly less than the number. The rightmost number among the equal numbers can determine the maximum left and right boundaries, so this method has no impact on the results.
answer
class Solution: def maxSumMinProduct(self, nums: List[int]) -> int: n = len(nums) pre_sums = nums[:] for i in range(1, n): pre_sums[i] += pre_sums[i - 1] pre_sums.append(0) right_less_poi, left_less_poi = [n] * n, [-1] * n stack = [] for i in range(n): while stack and nums[stack[-1]] >= nums[i]: right_less_poi[stack.pop()] = i if stack: left_less_poi[i] = stack[-1] stack.append(i) return max(num * (pre_sums[right - 1] - pre_sums[left]) for left, right, num in zip(left_less_poi, right_less_poi, nums)) % (10 ** 9 + 7)
Question 4
subject
Given a directed graph, it contains n nodes and m edges. Node numbers range from 0 to n-1. The string colors is a lowercase English letter, which indicates the color of the node in the figure. The two-dimensional array edges, where edges[j]=[aj, bj] indicates that there is a directed edge from node aj to node bj. The color value of the path is the number of nodes in the path that appear the most times. Returns the maximum color value in the valid path in the graph. If the figure contains a ring, return - 1.
Examples
Input: colors = "abaca", edges = [[0,1],[0,2],[2,3],[3,4]] Output: 3 Explanation: path 0 -> 2 -> 3 -> 4 Contains 3 colors "a" Node (red node in the figure above).
Idea (topological sorting + dynamic programming)
- We do not need to save every path. Take red as an example. In the process of transmission, we only need to know the maximum number of red nodes in the path ending with the parent node to determine the maximum number of red nodes in the path ending with the current node. Therefore, we only need to keep the maximum number of each color of each node
- Count the penetration of nodes, and add those whose penetration is 0 (no parent node) to the stack
- Pop the nodes out of the stack one by one, calculate the maximum number of nodes of various colors in the path ending with it, and update its child nodes based on this. If the child node has no uncalculated parent node, enter the stack
- When each node is out of the stack, all its parent nodes must be calculated, so it only needs to add its own color to complete the calculation
- If the total number of stacks is n, it means there is no ring, otherwise there is a ring (the nodes on the ring can never enter the stack, so they will not fall into an endless loop)
answer
class Solution: def largestPathValue(self, colors: str, edges: List[List[int]]) -> int: n = len(colors) colors = [ord(s) - 97 for s in colors] graph = [[] for _ in range(n)] visited = n in_deg = [0] * n for x, y in edges: in_deg[y] += 1 graph[x].append(y) rst = [[0] * 26 for _ in range(n)] stack = [i for i in range(n) if not in_deg[i]] while stack: node = stack.pop() visited -= 1 rst[node][colors[node]] += 1 for nei in graph[node]: in_deg[nei] -= 1 for color in range(26): rst[nei][color] = max(rst[nei][color], rst[node][color]) if not in_deg[nei]: stack.append(nei) return -1 if visited else max([max(rst[i]) for i in range(n)])