前言
复盘各种比赛,争取保持比赛时的那种压迫感,因为最近做题时,很懒散,然后大比赛时也吊儿郎当的,再加上比赛本来久紧张,所以出题数量很不理想。多学一点总没有错。
因为早上快飞升了,所以错过了比赛,下午做了以下虚拟赛,总共 AC 前
3
3
3 道题。
一、题目
题目 | 难度 |
---|---|
6090. 极大极小游戏 | ⭐️ |
6091. 划分数组使最大差为 K | ⭐️⭐️ |
6092. 替换数组中的元素 | ⭐️⭐️ |
6093. 设计一个文本编辑器 | ⭐️⭐️⭐️⭐️ |
二、算法思路
1、极大极小游戏
(1)直接暴力模拟可以过,建一个临时数组,按照题目所给的算法更新临时数组,然后将原数组替换,直到数组元素只有一个。
(2)时间复杂度:
O
(
1024
2
+
1024
4
+
…
…
+
1024
1024
)
=
O
(
2
n
+
1
)
=
O
(
2
n
)
=
1024
O(\frac{1024}{2}+\frac{1024}{4}+……+\frac{1024}{1024})=O(2^n+1)=O(2^n)=1024
O(21024+41024+……+10241024)=O(2n+1)=O(2n)=1024
class Solution {
public:
int minMaxGame(vector<int>& nums) {
while (nums.size() > 1) {
vector<int> v(nums.size() / 2);
for (int i = 0; i < v.size(); ++ i) {
if (i & 1) {
v[i] = max(nums[2 * i], nums[2 * i + 1]);
}
else {
v[i] = min(nums[2 * i], nums[2 * i + 1]);
}
}
nums = v;
}
return nums[0];
}
};
2、划分数组使最大差为 K
(1)首先将数组排序,遍历数组,第一个数为最小值,如果
n
u
m
s
[
i
]
>
m
i
n
+
k
nums[i]>min+k
nums[i]>min+k,那么更新最小值为
n
u
m
s
[
i
]
nums[i]
nums[i] 并且答案 +1,最后输出答案即可。
(2)时间复杂度:
O
(
n
log
n
+
n
)
O(n\log{n}+n)
O(nlogn+n)
class Solution {
public:
int partitionArray(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
int ans = 1;
int Min = nums[0] + k;
for (int i = 1; i < nums.size(); ++ i) {
if (nums[i] > Min) {
++ ans;
Min = nums[i] + k;
}
}
return ans;
}
};
3、替换数组中的元素
(1)首先开一个下标数组,然后遍历数组
n
u
m
s
nums
nums,记录
n
u
m
s
[
i
]
nums[i]
nums[i] 的下标
i
i
i。
(2)然后遍历数组
o
p
e
r
a
t
i
o
n
s
operations
operations,第
i
i
i 次操作,在下标数组
p
o
i
n
t
s
points
points 中获取
o
p
e
r
a
t
i
o
n
s
[
i
]
[
0
]
operations[i][0]
operations[i][0] 的下标,将
n
u
m
s
nums
nums 数组中对应的元素替换为
o
p
e
r
a
t
i
o
n
[
i
]
[
1
]
operation[i][1]
operation[i][1],随后更新
p
o
i
n
t
s
[
o
p
e
r
a
t
i
o
n
s
[
i
]
[
1
]
]
=
p
o
i
n
t
s
[
o
p
e
r
a
t
i
o
n
s
[
i
]
[
0
]
]
points[operations[i][1]]=points[operations[i][0]]
points[operations[i][1]]=points[operations[i][0]]。
(3)时间复杂度:
O
(
n
+
m
)
O(n+m)
O(n+m)
class Solution {
public:
vector<int> arrayChange(vector<int>& nums, vector<vector<int>>& operations) {
vector<int> points(1000010);
for (int i = 0; i < nums.size(); ++ i) {
points[nums[i]] = i;
}
for (auto x: operations) {
points[x[1]] = points[x[0]];
nums[points[x[0]]] = x[1];
}
return nums;
}
};
2、划分数组使最大差为 K
(1)首先,我的想法是维护两个字符串(光标前后两个字符串)以及一个下标,即光标的位置,主要使用的是 substr
来更新字符串,这个方法的时间复杂度是
O
(
l
e
n
)
O(len)
O(len),然后就是 TLE,AC 做法再去看看题解,附上自己写的 TLE 代码。
class TextEditor {
public:
TextEditor() {
idx = 0;
pre = "";
next = "";
//cout << "start" << endl;
}
void addText(string text) {
pre += text;
idx += text.size();
//cout << "add\t" << idx << '\t' << tex<< endl;
return;
}
int deleteText(int k) {
if (idx - k <= 0) {
pre = "";
int ret = idx;
idx = 0;
//cout << "del\t" << idx << '\t' << tex<< endl;
return ret;
}else {
pre = pre.substr(0, idx - k);
idx -= k;
//cout << "del\t" << idx << '\t' << tex<< endl;
return k;
}
}
string cursorLeft(int k) {
if (idx == 0)
return "";
if (idx <= k) {
idx = 0;
next = pre + next;
pre = "";
}else {
next = pre.substr(idx - k, k) + next;
pre = pre.substr(0, idx - k);
idx -= k;
}
return show();
}
string cursorRight(int k) {
if (next == "")
return show();
if (k >= next.size()) {
idx += next.size();
pre += next;
next = "";
}else {
pre += next.substr(0, k);
next = next.substr(k, next.size());
idx += k;
}
return show();
}
string show() {
int Min = min(idx, 10);
if (idx == Min)
return pre;
else
return pre.substr(idx - Min, Min);
}
int idx;
string pre, next;
};
/**
* Your TextEditor object will be instantiated and called as such:
* TextEditor* obj = new TextEditor();
* obj->addText(text);
* int param_2 = obj->deleteText(k);
* string param_3 = obj->cursorLeft(k);
* string param_4 = obj->cursorRight(k);
*/
结语
总结一下,出题速度还是慢,希望多做多敲了之后会快,然后就是思路转的不是很快,希望会好起来。平时做题的压迫感还是不够,甚至是没有。最后 Leetcode 永远的家,去写 CF、atcode,谷歌浏览器的翻译给我整吐了,强行翻译,排版还出错,最后还是看样例看英文出题,出的签到题😭,学英语去了。