LeetCode 第 220 场周赛 题解及思路
1694. 重新格式化电话号码
简要概况题目如下:
给定一个电话号码字符串
number
,由数字0-9
,空格' '
和破折号'-'
组成。要求输出 格式化 的电话号码。格式化要求:1. 删除所有非数字字符。2. 从左至右每 3 个一组,最后如果剩 4 个数字则变成每 2 个一组,否则最后少于等于 3 个数字独立为一组。3. 每组间用破折号'-'
连接。
简单题有简单题的做法,就是模拟,那就按照要求一个个来呗。首先我们筛选所有数字字符出来。
string nums;
for (const char& ch : number)
if ('0' <= ch && ch <= '9')
nums += ch;
然后每 3 个分为一组,并在后加上 '-'
。
int n = nums.size(), index = 0;
string ans;
while (index < n - 4) {
ans += nums.substr(index, 3) + "-";
index += 3;
};
注意最后 4 个字符特殊处理。
if (n - index == 4)
ans += nums.substr(index, 2) + "-" + nums.substr(index + 2, 2);
else if (index < n) ans += nums.substr(index);
else ans.pop_back(); // 抹掉最后一个字符 `-`
完整代码见 GitHub。
1695. 删除子数组的最大得分
给你一个正整数数组
nums
,请你从中删除一个含有 若干不同元素 的子数组。删除子数组的 得分 就是子数组各元素之 和。
返回 只删除一个 子数组可获得的 最大得分。
如果数组b
是数组a
的一个连续子序列,即如果它等于a[l], a[l + 1], ..., a[r]
,那么它就是a
的一个子数组。
提示
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^4
翻译题目意思,就是找到一个元素和最大且不含有相同元素的连续子数组。由于 nums[i]
都是正整数,理论上来说,如果不要求不含相同元素的话,答案就是整个数组。
所以,我们不停地向后遍历并将当前元素加入子数组中,一旦碰到了重复元素,那么我们就得重复元素的上一个数组下标,并从那里开始继续计算。
具体地,我们用两个指针 last
和 next
来记录当前子数组的左右边界,并用哈希表 counts
记录子数组中元素出现的次数。
unordered_map<int, int> counts;
int last = 0, next = 0, ans = 0, tmp = 0, n = nums.size();
然后将 next
指针往后遍历,并在 counts
中增加对应元素的出现次数,同时更新结果值 ans
。
while (next < n && !counts[nums[next]]) {
tmp += nums[next];
counts[nums[next]]++;
next++;
};