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; } };
评论
还没有任何评论,你来说两句吧!