T1重新格式化电话号码
思路
周赛经典的字符串处理题。难倒是不难,但是处理起来感觉比往期的签到题麻烦不少啊...
主要思路就是replace掉'-'与空格,然后每三个一组分片,塞进列表,最后再对单出来的元素特殊处理。
代码
class Solution:
def reformatNumber(self, number: str) -> str:
number = number.replace('-', '').replace(' ', '')
ans, N = [], len(number)
for i in range(0, N, 3):
ans.append(number[i:i+3])
if len(ans[-1]) == 1:
last = ans.pop()
sec_last = ans.pop()
ans.append(sec_last[:2])
ans.append(sec_last[-1]+last)
return '-'.join(ans)
字符串的题害得看我py。
T2 删除子数组的最大得分
思路
很标准的滑动窗口,很类似LeetCode003题,参考博文:LeetCode-003:无重复字符的最长子串。
枚举右边界,如果当前右指针指向的值已经在set里了,就从左往右去erase,一直erase到右指针指向的值已经不在set里了,这时集合中的值一定是无重复的。用cnt记录当前子区间的区间和,窗口每次滑动结束去维护一个最大的ans就行了。
代码
class Solution {
public:
int maximumUniqueSubarray(vector<int>& nums) {
unordered_set<int> mys;
int cnt = 0;
int ans = 0;
int l = 0;
for(int r = 0; r < nums.size(); r++) {
while(mys.find(nums[r]) != mys.end()) {
mys.erase(nums[l]);
cnt -= nums[l];
l++;
}
mys.insert(nums[r]);
cnt += nums[r];
ans = max(ans, cnt);
}
return ans;
}
};
T3跳跃游戏 VI
思路
显然是一道dp。设dp[i]表示位置i上能获取的最大价值,显然dp[i]=max{dp[i-1],dp[i-2],...,dp[i-k]}+nums[i]。
for (int i = 1; i < nums.size(); i++) {
for (int j = max(0, i - k); j < i; j++) {
dp[i] = max(dp[i], dp[j]);
}
dp[i] += nums[i];
}
但是这道题n与k能达到1e5的复杂度,直接O(n²)枚举显然超时,所以要另取巧。
因为要动态获取一个当前位置的最大值,考虑用大根堆。定义一个pair,以(dp[i],i)为关键字,维护一个此pair的大根堆,每次循环弹出所有越界(i - pair.second > k)元素,然后堆顶就是我们需要的动态最大值。
for(int i = 1; i < n; i++) {
// 移除越界元素
while(i - que.top().second > k) que.pop();
dp[i] = que.top().first + nums[i];
que.emplace(dp[i], i);
}
这个方法的时间复杂度是优越的,但空间还可以优化。显然,在这种做法下,当前状态的dp值不需要单独用一个数组去存,它们被抛入堆中动态维护,所以可以用一个变量来存当前状态下的答案:
for(int i = 1; i < n; i++) {
// 移除越界元素
while(i - que.top().second > k) que.pop();
ans = que.top().first + nums[i];
que.emplace(ans, i);
}
这样时空复杂度都是优秀的,LC上也能做到双百。
代码
class Solution {
public:
int maxResult(vector<int>& nums, int k) {
const int n = nums.size();
priority_queue< pair<int, int> > que;
que.emplace(nums[0], 0);
int ans = nums[0];
for(int i = 1; i < n; i++) {
// 移除越界元素
while(i - que.top().second > k) que.pop();
ans = que.top().first + nums[i];
que.emplace(ans, i);
}
return ans;
}
};