LeetCode-34
2789. 合并后数组中的最大元素
1 | class Solution { |
2864. 最大二进制奇数
- 一次遍历原地算法
1 | class Solution { |
1261. 在受污染的二叉树中查找元素
不要额外存储,不用恢复节点值
- 用对应满二叉树的标号标记index
- 判断要查的树在第几层,将标号转为0,1,2,3,…
- 二进制位就是搜索方向,找到null就是不存在,找到节点就是存在
1 | class FindElements { |
2129. 将标题首字母大写
1 | class Solution { |
310. 最小高度树
1 | class Solution { |
- 看了答案,拓扑排序,最后一批就是根
2684. 矩阵中移动的最大次数
- 暴力!暴力!
- 记忆优化搜索
1 | class Solution { |
303. 区域和检索 - 数组不可变
1 | class NumArray { |
前前前前前坠河(缀和)
2671. 频率跟踪器
- 两个hash表
1 | class FrequencyTracker { |
1969. 数组元素的最小非零乘积
- 根据小学知识,若
a+b=Constant
,则abs(a-b)
越大,a*b
越小 - 对于两个互补的数,如
10101
和01010
可以变成00001
和11110
,这样他们差距最大,乘积最小 00000
和11111
互补但是00000
不考虑,最后还要成员它- 只要计算有多少对互补数N,互补数的最小乘积A,答案等于
A^N*(全1)
1 | class Solution { |
取模的时候要注意优先级
*/%
是同级的,要加括号
1793. 好子数组的最大分数
- 一眼单调栈
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
32class Solution {
public:
int maximumScore(vector<int>& nums, int k) {
int len = nums.size();
vector<int> leftPos(len), rightPos(len);
stack<int> monoStack;
for(int i = 0; i < len; i++) {
leftPos[i] = i;
int top = -1;
while(!monoStack.empty() && nums[monoStack.top()] >= nums[i]) {
top = monoStack.top();
monoStack.pop();
}
if(top != -1) leftPos[i] = leftPos[top];
monoStack.push(i);
}
monoStack = stack<int>();
int ans = 0;
for(int i = len - 1; i >= 0; i--) {
int top = -1;
rightPos[i] = i;
while(!monoStack.empty() && nums[monoStack.top()] >= nums[i]) {
top = monoStack.top();
monoStack.pop();
}
if(top != -1) rightPos[i] = rightPos[top];
if(rightPos[i] >= k && k >= leftPos[i]) ans = max(ans, (rightPos[i] - leftPos[i] + 1) * nums[i]);
monoStack.push(i);
}
return ans;
}
};
蚂蚁2024年3月23日测评
第二题
- 给一个数组,对其中一个数自增0-1次,数组乘积最最多有几个0
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//
// Created by jingtian on 2024/3/23.
//
using namespace std;
int cntOf(int n, int divisor) {
int cnt = 0;
while(n % divisor == 0) {
cnt++;
n /= divisor;
}
return cnt;
}
int main() {
int n;
while(cin >> n) {
vector<int> arr(n);
int cntOf2 = 0, cntOf5 = 0;
for(int i = 0; i < n; i++) {
cin >> arr[i];
cntOf2 += cntOf(arr[i], 2);
cntOf5 += cntOf(arr[i], 5);
}
int ans = min(cntOf2, cntOf5);
for(int i = 0; i < n; i++) {
ans = max(ans, min(cntOf2 - cntOf(arr[i], 2) + cntOf(arr[i]+1, 2),
cntOf5 - cntOf(arr[i], 5) + cntOf(arr[i]+1, 5)));
}
cout << ans << endl;
}
return 0;
}
第三题
- 不知道AC没
- 给一颗数,每次将有公共点的两条边涂色,最多能涂色多少次,输出每次涂色的三个节点
- 贪心,对于倒数第二层的节点,两种情况
- 偶数个子节点
- 两两配对涂色
- 奇数个子节点
- 剩下一个和父节点涂色
- 其他层类似
- 偶数个子节点
1 | import java.io.ByteArrayOutputStream; |
2549. 统计桌面上的不同数字
- 记忆优化搜索
1 | class Solution { |