34. 棒球比赛(简单)
题目要求:
你现在是一场采用特殊赛制棒球比赛的记录员。这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分。
比赛开始时,记录是空白的。你会得到一个记录操作的字符串列表 ops,其中 ops[i] 是你需要记录的第 i 项操作,ops 遵循下述规则:
整数 x - 表示本回合新获得分数 x
“+” - 表示本回合新获得的得分是前两次得分的总和。题目数据保证记录此操作时前面总是存在两个有效的分数。
“D” - 表示本回合新获得的得分是前一次得分的两倍。题目数据保证记录此操作时前面总是存在一个有效的分数。
“C” - 表示前一次得分无效,将其从记录中移除。题目数据保证记录此操作时前面总是存在一个有效的分数。
请你返回记录中所有得分的总和。
题目解答:
#include <iostream>
using namespace std;
#include <string>
#include <vector>
#include <algorithm>
#include <unordered_map>
class Solution
{
public:
int calPoints(vector<string>& ops)
{
int ret = 0;
vector<int> points;
for (auto &op : ops)
{
int n = points.size(); // 每遍历一个元素,更新一次数组的尺寸
switch (op[0])
{
case '+': // 本回合新获得的得分是前两次得分的总和
ret += points[n - 1] + points[n - 2];
points.push_back(points[n - 1] + points[n - 2]); // 入栈
break;
case 'D': // 本回合新获得的得分是前一次得分的两倍
ret += 2 * points[n - 1];
points.push_back(2 * points[n - 1]);
break;
case 'C': // 前一次得分无效,将其从记录中移除
ret -= points[n - 1];
points.pop_back(); // 出栈
break;
default: // 默认直接插入数字
ret += stoi(op);
points.push_back(stoi(op));
break;
}
}
return ret;
}
};
int main()
{
vector<string> ops = { "5","2","C","D","+" };
Solution s;
int res = s.calPoints(ops);
cout << "操作列表为:" << endl;
for (auto &op : ops)
{
cout << op << ", ";
}
cout << endl;
cout << "根据规则,总得分为:" << res << endl;
system("pause");
return 0;
}
35. 数组的度(重要)(中等)
题目要求:
给定一个非空且只包含非负数的整数数组 nums,数组的 度 的定义是指数组里任一元素出现频数的最大值。
在 nums 中找到与 nums 拥有相同大小的度
的最短
连续子数组,返回其长度。
题目解答:
#include <iostream>
using namespace std;
#include <string>
#include <vector>
#include <algorithm>
#include <unordered_map>
class Solution
{
public:
int findShortestSubArray(vector<int>& nums)
{
// 创建map容器,每个元素值映射到长度为3的数组
// 数组包含:这个数出现的次数,这个数在原数组中第一次出现的位置,这个数在原数组中最后一次出现的位置
unordered_map<int, vector<int>> mp;
int n = nums.size();
for (int i = 0; i < n; i++)
{
if (mp.count(nums[i])) // 元素不是第一次出现
{
mp[nums[i]][0]++; // 出现次数+1
mp[nums[i]][2] = i; // 最后一次出现的位置为i
}
else // 元素第一次出现
{
mp[nums[i]] = { 1, i, i }; // 出现1次,第一次出现的位置和最后一次出现的位置都为i
}
}
int maxNum = 0, minLen = 0; // 记录元素出现的最高次数和包含这些元素的子数组的最小长度
for (auto& e : mp)
{
if (maxNum < e.second[0]) // 如果maxNum小于此时元素出现的次数
{
maxNum = e.second[0]; // 更新maxNum
minLen = e.second[2] - e.second[1] + 1; // 更新minLen
}
else if (maxNum == e.second[0]) // 如果maxNum等于此时元素出现的次数
{
if (minLen > e.second[2] - e.second[1] + 1) // 如果minLen大于包含此时元素的子数组的长度
{
minLen = e.second[2] - e.second[1] + 1; // 更新minLen
}
}
}
return minLen;
}
};
int main()
{
vector<int> nums = { 1,2,2,3,1,4,2 };
Solution s;
int res = s.findShortestSubArray(nums);
cout << "和原数组的度相同且长度最小的子数组长度为:" << res << endl;
system("pause");
return 0;
}
36. 二分查找(简单)
题目要求:
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
题目解答:
#include <iostream>
using namespace std;
#include <string>
#include <vector>
#include <algorithm>
class Solution
{
public:
int searchNum(vector<int>& nums, int target)
{
int left = 0, right = nums.size() - 1;
while (left <= right)
{
int mid = (right - left) / 2 + left;
int num = nums[mid]; // 取区间中位数和target比较
if (num == target)
{
return mid;
}
else if (num > target) // 如果此时区间中位数大于目标值,区间右界左移
{
right = mid - 1;
}
else // 如果此时区间中位数小于目标值,区间左界右移
{
left = mid + 1;
}
}
return -1;
}
};
int main()
{
vector<int> nums = { -1,0,3,5,9,12 };
int findNum = 0;
int breakFlag = 0;
Solution s;
while (true)
{
cout << "此次查找后是否退出系统?1--是,2--否: ";
cin >> breakFlag;
if (breakFlag == 1)
{
cout << "请输入要查找的数:";
cin >> findNum;
int res = s.searchNum(nums, findNum);
if (res == -1)
{
cout << "该元素不存在!" << endl;
}
else
{
cout << "该元素存在,且在数组中的下标为:" << res << endl;
}
break;
}
else if (breakFlag == 2)
{
cout << "请输入要查找的数:";
cin >> findNum;
int res = s.searchNum(nums, findNum);
if (res == -1)
{
cout << "该元素不存在!" << endl;
system("pause");
system("cls");
}
else
{
cout << "该元素存在,且在数组中的下标为:" << res << endl;
system("pause");
system("cls");
}
}
else
{
cout << "输入有误,重新输入!" << endl;
system("pause");
system("cls");
}
}
system("pause");
return 0;
}