题目
-
重新格式化电话号码
-
删除子数组的最大得分
-
跳跃游戏 VI
思路与算法
- 简单的string操作,用cpp或者java均可。
- 使用一个map来维护当前值出现的次数和当前值。判断值出现的次数大于1时重复,那么再维护指向第一个不重复的数字的索引即可。
- 滑动窗口dp即可,注意不剪枝会TLE,详细见注释
代码实现
- 重新格式化电话号码
class Solution {
public:
string reformatNumber(string number) {
// ans 用来返回,buf 用来把原来数据中的数字保存
string ans, buf;
// 对所有数字保存下来
for (char c : number) if (c != ' ' && c != '-') buf.push_back(c);
// 对缓冲区中的数据进行挨个分组处理
for (int i = 0; i < buf.size(); ++i) {
// 如果遇到分割边界,而且不是开头和末尾的特殊情况,那么就直接拼接分隔符 -
if (i != 0 && i % 3 == 0 && buf.size() - i > 1) {
ans.push_back('-');
} else if (i != 0 && i % 3 == 0 && i == buf.size() - 1) {
// 否则就修改最后的两组数据
char c = ans.back();
ans.pop_back();
ans.push_back('-');
ans.push_back(c);
}
ans.push_back(buf[i]);
}
return ans;
}
};
- 删除子数组的最大得分
class Solution {
public:
int maximumUniqueSubarray(vector<int>& nums) {
unordered_map<int,int> map;
int n = nums.size();
int res = 0, s = 0;
for(int i = 0, j = 0; i < n; i++){
map[nums[i]]++;
s += nums[i];
while(map[nums[i]] > 1){
map[nums[j]]--;
s -= nums[j];
j++;
}
res = max(res, s);
}
return res;
}
};
- 跳跃游戏 VI
class Solution {
public int maxResult(int[] nums, int k) {
int len = nums.length;
int[] dp = new int[len];
// dp数组初始化
for (int i = 0; i < len; i++) {
dp[i] = Integer.MIN_VALUE;
}
// dp[x]表示以索引x为终点的最大得分。那么能一跳到达x的索引范围为[x-k,x-1]。
dp[0] = nums[0];
// 遍历从i到i可以一跳到达的落点j,j的索引范围为[i+1,i+k],
for (int i = 0; i < len; i++) {
for (int j = i + 1; (j <= i + k) && (j < len); j++) {
// 如果比j位置当前最大得分大, 则更新j位置最大得分
dp[j] = Math.max(dp[i] + nums[j],dp[j]);
// 剪枝:如果上式更新后的dp[j]比dp[i]大,也就是可以获取得分提升,因此直接跳出即可完成优化通过本题。
if (dp[j] >= dp[i]) {
break;
}
}
}
return dp[len - 1];
}
}
写在最后
- 第4题写不出来,日常卡第四题。立个flag,202年1月份之内补上此类的数据结构空缺