leetcode biweekly contest 130
t4
又是一个难的数学题目。
3142. 判断矩阵是否满足条件
给你一个大小为 m x n
的二维矩阵 grid
。你需要判断每一个格子 grid[i][j]
是否满足:
- 如果它下面的格子存在,那么它需要等于它下面的格子,也就是
grid[i][j] == grid[i + 1][j]
。 - 如果它右边的格子存在,那么它需要不等于它右边的格子,也就是
grid[i][j] != grid[i][j + 1]
。
如果 所有 格子都满足以上条件,那么返回 true
,否则返回 false
。
示例 1:
输入:grid = [[1,0,2],[1,0,2]]
输出:true
解释:
网格图中所有格子都符合条件。
示例 2:
输入:grid = [[1,1,1],[0,0,0]]
输出:false
解释:
同一行中的格子值都相等。
示例 3:
输入:grid = [[1],[2],[3]]
输出:false
解释:
同一列中的格子值不相等。
提示:
1 <= n, m <= 10
0 <= grid[i][j] <= 9
地址
https://leetcode.cn/contest/biweekly-contest-130/problems/check-if-grid-satisfies-conditions/
题意
直接模拟
思路
- 直接模拟即可,检测每个元素是否满足题目要求即可。
- 复杂度分析:
- 时间复杂度:$O(mn)$。
- 空间复杂度:$O(1)$。
代码
class Solution: |
impl Solution { |
3143. 正方形中的最多点数
给你一个二维数组 points
和一个字符串 s
,其中 points[i]
表示第 i
个点的坐标,s[i]
表示第 i
个点的 标签 。
如果一个正方形的中心在 (0, 0)
,所有边都平行于坐标轴,且正方形内 不 存在标签相同的两个点,那么我们称这个正方形是 合法 的。
请你返回 合法 正方形中可以包含的 最多 点数。
注意:
- 如果一个点位于正方形的边上或者在边以内,则认为该点位于正方形内。
- 正方形的边长可以为零。
示例 1:
输入:points = [[2,2],[-1,-2],[-4,4],[-3,1],[3,-3]], s = “abdca”
输出:2
解释:
边长为 4 的正方形包含两个点 points[0]
和 points[1]
。
示例 2:
输入:points = [[1,1],[-2,-2],[-2,2]], s = “abb”
输出:1
解释:
边长为 2 的正方形包含 1 个点 points[0]
。
示例 3:
输入:points = [[1,1],[-1,-1],[2,-2]], s = “ccd”
输出:0
解释:
任何正方形都无法只包含 points[0]
和 points[1]
中的一个点,所以合法正方形中都不包含任何点。
提示:
1 <= s.length, points.length <= 105
points[i].length == 2
-109 <= points[i][0], points[i][1] <= 109
s.length == points.length
points
中的点坐标互不相同。s
只包含小写英文字母。
地址
https://leetcode.cn/contest/biweekly-contest-130/problems/maximum-points-inside-the-square/
题意
贪心,二分查找
思路
- 我们知道对于一个点 $(x, y)$ 处于边长为 $2l$ 的正方形中,此时需要满足 $\max(|x|, |y|) \le l$,此时我们按照所有点的坐标的最大值进行排序,每次计算在给定的范围内,计算当前范围构成的正方形是否存在两个标签相同的点即可。当然另一种方法是二分查找,思路比较简单,在此不再描述。
- 复杂度分析:
- 时间复杂度:$O(n \log n)$,其中 $n$ 表示给定的数组的长度。
- 空间复杂度:$O(n)$,其中 $n$ 表示给定的数组的长度。
代码
class Solution: |
3144. 分割字符频率相等的最少子字符串
给你一个字符串 s
,你需要将它分割成一个或者更多的 平衡 子字符串。比方说,s == "ababcc"
那么 ("abab", "c", "c")
,("ab", "abc", "c")
和 ("ababcc")
都是合法分割,但是 ("a", **"bab"**, "cc")
,(**"aba"**, "bc", "c")
和 ("ab", **"abcc"**)
不是,不平衡的子字符串用粗体表示。
请你返回 s
最少 能分割成多少个平衡子字符串。
注意:一个 平衡 字符串指的是字符串中所有字符出现的次数都相同。
示例 1:
输入:s = “fabccddg”
输出:3
解释:
我们可以将 s
分割成 3 个子字符串:("fab, "ccdd", "g")
或者 ("fabc", "cd", "dg")
。
示例 2:
输入:s = “abababaccddb”
输出:2
解释:
我们可以将 s
分割成 2 个子字符串:("abab", "abaccddb")
。
提示:
1 <= s.length <= 1000
s
只包含小写英文字母。
地址
题意
滑动窗口
思路
题目本身不是太难,主要是如果暴力统计的话 $26n^2$ 的复杂度会超时,此时需要进一步优化,我们直接统计区间 $[i,j]$ 中每个字符出现的频次,每次 $j$ 移动时,同时更新字符 $s[j]$ 的频次,检测如果区间内只存在一个频次的即为合法的分割 。 稍微需要一点技巧,我们用一个哈希表 $freq$ 统计频次出现的次数,实时动态更新,当 $freq$ 中只有一个频次时,则该分割为合法分割。
复杂度:
- 时间复杂度:$O(n^2)$,其中 $n$ 表示给定的字符串的长度;
- 空间复杂度:$O(n)$;
代码
class Solution: |
3145. 大数组元素的乘积
一个整数 x
的 强数组 指的是满足和为 x
的二的幂的最短有序数组。比方说,11 的强数组为 [1, 2, 8]
。
我们将每一个正整数 i
(即1,2,3等等)的 强数组 连接得到数组 big_nums
,big_nums
开始部分为 [1, 2, 1, 2, 4, 1, 4, 2, 4, 1, 2, 4, 8, ...]
。
给你一个二维整数数组 queries
,其中 queries[i] = [fromi, toi, modi]
,你需要计算 (big_nums[fromi] * big_nums[fromi + 1] * ... * big_nums[toi]) % modi
。
请你返回一个整数数组 answer
,其中 answer[i]
是第 i
个查询的答案。
示例 1:
输入:queries = [[1,3,7]]
输出:[4]
解释:
只有一个查询。
big_nums[1..3] = [2,1,2]
。它们的乘积为 4 ,4 对 7 取余数得到 4 。
示例 2:
输入:queries = [[2,5,3],[7,7,4]]
输出:[2,2]
解释:
有两个查询。
第一个查询:big_nums[2..5] = [1,2,4,1]
。它们的乘积为 8 ,8 对 3 取余数得到 2 。
第二个查询:big_nums[7] = 2
,2 对 4 取余数得到 2 。
提示:
1 <= queries.length <= 500
queries[i].length == 3
0 <= queries[i][0] <= queries[i][1] <= 1015
1 <= queries[i][2] <= 105
地址
https://leetcode.cn/contest/biweekly-contest-130/problems/find-products-of-elements-of-big-array/
题意
二分查找,数学,位运算
思路
题目算是比较难的数学题目,但确实是个比较值得思考的题目。也可以说是一个数学题目,分析如下:
我们先来计算一个问题,$[1,2^i]$ 组成的强数组中有多少个元素?所有元素组成的乘积又是 $2$ 的多少次幂数?此事直接计算似乎不太好计算,但是我们可以参考力扣中的一个题目: [1969. 数组元素的最小非零乘积] 。
$[1,2^i]$ 可以组成的元素本质即统计所有元素中 $1$ 的个数,通过 [1969. 数组元素的最小非零乘积] 可以知道,我们可以通过交换,可以将区间 $[1,2^i-1]$ 数在相同位上进行交换刚好可以组成 $2^{i-1}$ 个 $2^{i}-1$,即 $sum_{j=1}^{2^i - 1} = 2^{i-1} \times (2^i-1)$,此时再加上 $2^i$ ,由于每个 $2^{i} - 1$ 可以拆分为 $i$ 个 $2$ 的幂数,此时再加上 $2^i$ ,此时 $[1,2^i]$ 组成的强数组中含有的元素数目即为 $f(i) = i\times 2^{i-1} + 1$ 个;
$[1,2^i]$ 可以组成的元素本质即统计所有元素中 $1$ 的个数,通过 [1969. 数组元素的最小非零乘积] 可以知道,我们可以通过交换,可以将区间 $[1,2^i-1]$ 数在相同位上进行交换刚好可以组成 $2^{i-1}$ 个 $2^{i}-1$,即 $sum_{j=1}^{2^i - 1} = 2^{i-1} \times (2^i-1)$,此时再加上 $2^i$ ,由于 $2^0$ 的幂数为 $0$,此时每个 $2^{i} - 1$ 可以拆分为 $2$ 的幂数即为 $1 + 2 + 3 + \cdots + i - 2 + i - 1 = \dfrac{i \times (i - 1)}{2}$,此时再加上 $2^i$ 的幂数为 $i$,此时可以得到 $[1,2^i]$ 组程的强数组元素乘积中 $2$ 的幂数为 $g(i) = \dfrac{i \times (i - 1)}{2} + 1$ ;
我们再来观察 $[1,x]$ 组成的强数组中的元素数目,设 $f(x)$ 表示 $[1,x]$ 的元素含有的元素数目,对 $x$ 来说,假设$x = 2^{c_0} + 2^{c_1} + \cdots 2^{c_{m-1}}$, 此时所有小于等于 $2^{c_0}$ 的元素数目即为 $f(i)$, 所有大于 $2^{c_0}$ 的元素来说都含有一个元素为 $2^{c_0}$, 此时可以得到 $f(x) = f(2^{c_0}) + (x - 2^{c0}) + f(x - 2^{c_0})$, 此时我们很容易得到递推公式为:
$$
f(x) = f(2^{c_0}) + f(2^{c_1}) + \cdots + f(2^{c_{m-1}}) + x - 2^{c_0} + x - 2^{c_0} - 2^{c_1} \cdots + x -2^{c_0} - 2^{c_1} - \cdots 2^{c_{m-1}} \
= \sum_{i=0}^{m-1}f(2^{c_i}) + (m - 1) \times 2^{c_{m-1}} + (m - 1) \times 2^{c_{m-2}} + \cdots + 2^{c_{1}}
$$我们再来计算 $[1,x]$ 组成的强数组中乘积 $2$ 的幂数,设 $g(x)$ 表示 $[1,x]$ 的元素含有的元素数目,对 $x$ 来说,假设$x = 2^{c_0} + 2^{c_1} + \cdots 2^{c_{m-1}}$, 此时所有小于等于 $2^{c_0}$ 的元素乘积构成的幂数即为 $g(i)$, 所有大于 $2^{c_0}$ 的元素来说都含有一个元素为 $2^{c_0}$, 此时可以得到 $f(x) = f(2^{c_0}) + c_0 \times (x - 2^{c0}) + f(x - 2^{c_0})$, 此时我们很容易得到递推公式为:
$$
f(x) = f(2^{c_0}) + f(2^{c_1}) + \cdots + f(2^{c_{m-1}}) + c_0 \times (x - 2^{c_0}) + c_1 \times (x - 2^{c_0} - 2^{c_1}) \cdots + c_{m-1} \times (x -2^{c_0} - 2^{c_1} - \cdots 2^{c_{m-1}}) \
$$
根据 $1$ 的分析我们再回到问题本身来看每次需要计算 $[x,y]$ 之间的乘积,此时我们需要找到 $[1,x-1]$ 之间乘积的幂数 $c_0$,然后再找到 $[1,y]$ 之间的幂数 $c_1$ ,此时 $c_1 - c_0$ 即等于 $[x,y]$ 之间的幂数,由于我们很容易可以通过二分查找找到 $x$ 个强数组元素中最大元素 $a$,此时再找到 $y$ 个强数组元素中的最大元素 $b$,由于 $x$ 个元素很有可能并不刚好满足 $[1,a]$ ,此时需要处理边界问题,将最高位的去掉即可。然后我们找到满足题目要求即可,然后计算出所有幂数, 然后用快速幂计算并取模返回即可。
复杂度分析:
- 时间复杂度:$O(n \times \log^2 U)$,其中 $n$ 表示给定查询的数组的长度, $U$ 表示给定查询中元素的最大数目;
- 空间复杂度:$O(1ogU)$, $U$ 表示给定查询中元素的最大数目;
代码
class Solution { |
欢迎关注和打赏,感谢支持!
关注我的博客: https://mike-box.github.io/
关注我的微信公众号: 哪些奋斗者
扫描二维码,分享此文章