第 296 场周赛
Problem A - 极大极小游戏
方法一:模拟
- 时间复杂度 。
- 空间复杂度 。
参考代码(Python 3)
class Solution:
def minMaxGame(self, nums: List[int]) -> int:
while len(nums) > 1:
nxt = []
for i in range(0, len(nums), 2):
if i % 4 == 0:
nxt.append(min(nums[i:i+2]))
else:
nxt.append(max(nums[i:i+2]))
nums = nxt
return nums[0]
Problem B - 划分数组使最大差为 K
方法一:排序 + 贪心
排序后从小到大分组即可。
- 时间复杂度 。
- 空间复杂度 。
参考代码(Python 3)
class Solution:
def partitionArray(self, nums: List[int], k: int) -> int:
nums.sort()
ans = 1
l = nums[0]
for num in nums[1:]:
if num - l > k:
ans += 1
l = num
return ans
Problem C - 替换数组中的元素
方法一:记录双向映射
在本题的限制条件下,记录并维护从原始数值到当前数值,以及从当前数值到原始数值的双向映射即可。
- 时间复杂度 。
- 空间复杂度 。
参考代码(Python 3)
class Solution:
def arrayChange(self, nums: List[int], operations: List[List[int]]) -> List[int]:
mapping = {num: num for num in nums}
original = {num: num for num in nums}
for u, v in operations:
raw = original[u]
mapping[raw] = v
original[v] = raw
del original[u]
return [mapping[num] for num in nums]
思考
如果去掉题目中的限制条件,也即:
- 数组中可能包含相同的数字。
- 每次操作 中, 可能不存在, 可能存在。
要如何解决呢?
提示
两组数一旦合并(变成相同的数值)之后无论如何操作都不会分开。因此可以使用并查集来维护每个数值分组。
Problem D - 设计一个文本编辑器
方法一:链表模拟
list
)const int LEN = 10;
class TextEditor {
list<char> lst;
list<char>::iterator c;
string fetch() {
auto it = c;
string s;
for (int k = LEN; k > 0 && *prev(it) != ' '; k--, it = prev(it)) s.push_back(*prev(it));
reverse(s.begin(), s.end());
return s;
}
public:
TextEditor() {
lst = list<char> {' '};
c = lst.end();
}
void addText(string text) {
for (char ch : text) c = next(lst.insert(c, ch));
}
int deleteText(int k) {
int i = 0;
for (; k > 0 && *prev(c) != ' '; k--, i++, c = lst.erase(prev(c))) {}
return i;
}
string cursorLeft(int k) {
for (; k > 0 && *prev(c) != ' '; k--, c = prev(c)) {}
return fetch();
}
string cursorRight(int k) {
for (; k > 0 && c != lst.end(); k--, c = next(c)) {}
return fetch();
}
};
const int LEN = 10;
struct Node {
char ch;
Node *pre, *nxt;
Node(char c) : ch(c), pre(nullptr), nxt(nullptr) {}
};
class TextEditor {
Node *c;
string fetch() {
Node *p = c;
string s;
for (int k = LEN; k > 0 && p->ch != ' '; k--, p = p->pre) s.push_back(p->ch);
reverse(s.begin(), s.end());
return s;
}
public:
TextEditor() { c = new Node(' '); }
void addText(string text) {
for (char ch : text) {
Node *n = new Node(ch);
n->pre = c;
n->nxt = c->nxt;
if (c->nxt != nullptr) c->nxt->pre = n;
c->nxt = n;
c = n;
}
}
int deleteText(int k) {
int i = 0;
for (; k > 0 && c->ch != ' '; k--, i++, c = c->pre) {
c->pre->nxt = c->nxt;
if (c->nxt != nullptr) c->nxt->pre = c->pre;
}
return i;
}
string cursorLeft(int k) {
for (; k > 0 && c->ch != ' '; k--, c = c->pre) {}
return fetch();
}
string cursorRight(int k) {
for (; k > 0 && c->nxt != nullptr; k--, c = c->nxt) {}
return fetch();
}
};
:::
方法二:栈模拟
参考代码(C++)
const int LEN = 10;
class TextEditor {
stack<char> L, R;
string fetch() {
string s;
for (int i = 0; i < LEN && !L.empty(); ++i) s.push_back(L.top()), L.pop();
reverse(s.begin(), s.end());
for (char ch : s) L.push(ch);
return s;
}
public:
TextEditor() {}
void addText(string text) {
for (char ch : text) L.push(ch);
}
int deleteText(int k) {
int i = 0;
for (; i < k && !L.empty(); ++i) L.pop();
return i;
}
string cursorLeft(int k) {
for (int i = 0; i < k && !L.empty(); ++i) R.push(L.top()), L.pop();
return fetch();
}
string cursorRight(int k) {
for (int i = 0; i < k && !R.empty(); ++i) L.push(R.top()), R.pop();
return fetch();
}
};