Rank
Name
Score
Finish Time
Q1 (3)
Q2 (5)
Q3 (5)
Q4 (6)
120 / 12076
YoungForest
18
1:19:33
0:03:17
0:09:23 🐞1
0:26:15
1:04:33 🐞2
继续保持好成绩,尤其是最后一题,还是挺难的。刚开始没有思路甚至想放弃,但最后还是靠自己的思考解决了难题。
1893. Check if All the Integers in a Range Are Covered
签到题。对于[right, right]
中每一个数,判断是否被ranges
中的某个区间包含。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution {public : bool isCovered (vector<vector<int >>& ranges, int left, int right) { auto cover = [&](const int i) -> bool { for (const auto & range : ranges) { const int l = range[0 ], r = range[1 ]; if (l <= i && i <= r) return true ; } return false ; }; for (int i = left; i <= right; ++i) { if (!cover (i)) return false ; } return true ; } };
时间复杂度: O((right - left) * ranges.length),
空间复杂度: O(1).
1894. Find the Student that Will Replace the Chalk
先求前缀和,把k和和取余数,可以定位到最后一轮的遍历。然后用二分搜索寻找恰好大于k的位置,即为需要更换粉笔的学生。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution { using ll = long long ; public : int chalkReplacer (vector<int >& chalk, int k) { const int n = chalk.size (); vector<ll> presum (n + 1 ) ; presum[0 ] = 0 ; for (int i = 0 ; i < n; ++i) { presum[i+1 ] = presum[i] + chalk[i]; } if (k >= presum.back ()) { k = k % presum.back (); } auto it = upper_bound (presum.begin (), presum.end (), k); return distance (presum.begin (), it) - 1 ; } };
时间复杂度: O(N + log N), N = chalk.length,
空间复杂度: O(chalk.length).
需要注意数据范围,计算前缀和时可能会int
溢出。我也因此Runtime Error一次。换成long long
就好了。LeetCode最近坑溢出的case越来越多了,以后遇到需要先预估一下最大的值,该用long long
用long long
.
1895. Largest Magic Square
暴力法:从大到小枚举所有的正方形,计算所有行、列、对角的和,判断是否相等。唯一的优化是采用前缀和,快速计算行列和。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 class Solution {public : int largestMagicSquare (vector<vector<int >>& grid) { const int m = grid.size (); const int n = grid[0 ].size (); vector<vector<int >> presumLeft (m, vector <int >(n + 1 )); for (int i = 0 ; i < m; ++i) { presumLeft[i][0 ] = 0 ; for (int j = 0 ; j < n; ++j) { presumLeft[i][j+1 ] = presumLeft[i][j] + grid[i][j]; } } vector<vector<int >> presumUp (m + 1 , vector <int >(n)); for (int j = 0 ; j < n; ++j) { presumUp[0 ][j] = 0 ; } for (int j = 0 ; j < n; ++j) { for (int i = 0 ; i < m; ++i) { presumUp[i+1 ][j] = presumUp[i][j] + grid[i][j]; } } auto check = [&](const int i, const int j, const int k) -> bool { int target = presumLeft[i][j+k] - presumLeft[i][j]; for (int row = 1 ; row < k; ++row) { if (target != presumLeft[i+row][j+k] - presumLeft[i+row][j]) return false ; } for (int col = 0 ; col < k; ++col) { if (target != presumUp[i+k][j+col] - presumUp[i][j+col]) return false ; } { int diagonal = 0 ; for (int row = 0 ; row < k; ++row) { diagonal += grid[i+row][j+row]; } if (diagonal != target) return false ; } { int diagonal = 0 ; for (int row = 0 ; row < k; ++row) { diagonal += grid[i+row][j+k-1 -row]; } if (diagonal != target) return false ; } return true ; }; for (int k = min (n, m); k > 0 ; --k) { for (int i = 0 ; i < m; ++i) { for (int j = 0 ; j < n; ++j) { if (i + k <= m && j + k <= n && check (i, j, k)) return k; } } } return 1 ; } };
时间复杂度: O(N^4),
空间复杂度: O(N^2).
1896. Minimum Cost to Change the Final Value of Expression
递归,根据 & | 和 子表达式的值 进行分类,寻找最小cost。
括号的处理需要提前用栈,找到所有的配对。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 class Solution : def minOperationsToFlip (self, expression: str ) -> int : n = len (expression) leftPair = {} left = 0 leftStack = [] for i in range (n): if expression[i] == ')' : left -= 1 leftPair[i] = leftStack.pop() elif expression[i] == '(' : left += 1 leftStack.append(i) def dp (i, j ): if i + 1 == j: return expression[i] == '1' , 1 else : if expression[j-1 ] == ')' : leftIndex = leftPair[j-1 ] if leftIndex == i: return dp(i+1 ,j-1 ) pivot = leftIndex - 1 else : pivot = j - 2 if expression[pivot] == '0' or expression[pivot] == '1' : pivot -= 1 leftResult, leftCost = dp(i, pivot) rightResult, rightCost = dp(pivot+1 , j) if expression[pivot] == '|' : if leftResult == False and rightResult == False : return False , min (leftCost, rightCost) elif leftResult == True and rightResult == False : return True , 1 elif leftResult == False and rightResult == True : return True , 1 else : return True , min (leftCost + 1 , rightCost + 1 ) elif expression[pivot] == '&' : if leftResult == False and rightResult == False : return False , min (leftCost + 1 , rightCost + 1 ) elif leftResult == True and rightResult == False : return False , 1 elif leftResult == False and rightResult == True : return False , 1 else : return True , min (leftCost, rightCost) return dp(0 , len (expression))[1 ]
时间复杂度: O(N),
空间复杂度: O(N).