19. 最大连续 1 的个数(简单)
题目要求:
给定一个二进制数组nums
, 计算其中最大连续 1 的个数。
题目解答:
#include <iostream>
using namespace std;
#include <string>
#include <vector>
#include <algorithm>
class Solution
{
public:
int findMaxConsecutiveOnes(vector<int>& nums)
{
int count = 0;
int maxCount = 0;
int n = nums.size();
for (int i = 0; i < n; i++)
{
if (nums[i] == 1) // 遍历整个数组,若元素为1则计数
{
count++;
}
else
{
maxCount = max(maxCount, count); // 每次连续计数后在maxCount中更新
count = 0; // 将临时计数器置零
}
}
maxCount = max(maxCount, count); // 如果数组末尾为1,也会计数,此时for循环不会计数,需在循环结束后额外计数一次
return maxCount;
}
};
int main()
{
vector<int>nums = { 1,1,0,1,1,1 };
Solution s;
int res = s.findMaxConsecutiveOnes(nums);
cout << "最大连续1的个数为:" << res << endl;
system("pause");
return 0;
}
20. 提莫攻击(有趣)(简单)
题目要求:
在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄。他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态。
当提莫攻击艾希,艾希的中毒状态正好持续duration
秒。
提莫在t
发起攻击意味着艾希在时间区间[t, t + duration - 1]
(含 t 和 t + duration - 1)处于中毒状态。如果提莫在中毒影响结束前
再次攻击,中毒状态计时器将会重置
,在新的攻击之后,中毒影响将会在duration
秒后结束。
给定一个非递减
的整数数组timeSeries
,其中timeSeries[i]
表示提莫在timeSeries[i]
秒时对艾希发起攻击,以及一个表示中毒持续时间的整数 duration
。
返回艾希处于中毒状态的总秒数。
题目解答:
#include <iostream>
using namespace std;
#include <string>
#include <vector>
#include <algorithm>
class Solution
{
public:
int findPoisonedDuration(vector<int>& timeSeries, int duration)
{
int ans = 0, expireTime = 0; // 初始化总中毒时间和此次中毒的结束时刻
for (int i = 0; i < timeSeries.size(); i++)
{
if (timeSeries[i] >= expireTime) // 如果发起攻击的时刻超过上一次中毒的结束时刻,只需再增加一次持续时间
{
ans += duration;
}
else
{
ans += timeSeries[i] + duration - expireTime; // 如果发起攻击的时刻未超过上一次中毒的结束时刻,需增加一次持续时间-上一次中毒结束时刻
}
expireTime = timeSeries[i] + duration; // 更新中毒时刻
}
return ans;
}
};
int main()
{
vector<int>nums;
int startNum = 0;
int duration = 0;
cout << "请输入提莫发起攻击的时刻:" << endl;
do {
cin >> startNum;
nums.push_back(startNum);
} while (getchar() != '\n'); // 用户输入攻击时刻,以空格分隔
cout << "请输入艾希中毒的持续时间:" << endl;
cin >> duration;
Solution s;
int res = s.findPoisonedDuration(nums, duration);
cout << "艾希中毒的总持续时间为:" << res << endl;
system("pause");
return 0;
}
21. 下一个更大元素(重要)
题目要求:
nums1中数字x的下一个更大元素
是指 x 在 nums2 中对应位置右侧的第一个比x大的元素
。
给定两个没有重复元素
的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集
。
对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 nums2[j] 的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1 。
返回一个长度为 nums1.length 的数组 ans 作为答案,满足 ans[i] 是如上所述的下一个更大元素
。
题目分析:
此题解法为单调栈解,涉及求下一个最大元素,就用单调栈解。
题目解答:
#include <iostream>
using namespace std;
#include <string>
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <stack>
class Solution
{
public:
vector<int> nextBiggerNum(vector<int>& nums1, vector<int>& nums2)
{
unordered_map<int, int> hashmap;
stack<int> st;
for (int i = nums2.size() - 1; i >= 0; i--)
{
int num = nums2[i]; // 从后往前遍历nums2
while (!st.empty() && num >= st.top()) // 当栈不为空且此时num的值>=栈顶元素值时执行循环
{
st.pop(); // 栈顶元素出栈(根据循环执行的条件,此时栈顶元素不可能是其左边元素的下一个更大数)
}
hashmap[num] = st.empty() ? -1 : st.top(); // 如果栈为空返回-1(此时num没有下一个更大数),否则返回栈顶元素(此时栈顶元素就是num的下一个更大数)
st.push(num); // 将此时的num入栈
}
vector<int> res(nums1.size());
for (int i = 0; i < nums1.size(); i++)
{
res[i] = hashmap[nums1[i]]; // 此时hashmap中存放了由nums2中每个元素和其下一个更大元素构成的键值对
}
return res;
}
};
int main()
{
vector<int>nums1;
vector<int>nums2;
int startNum1 = 0;
int startNum2 = 0;
cout << "请输入nums2的元素:" << endl;
do {
cin >> startNum2;
nums2.push_back(startNum2);
} while (getchar() != '\n');
cout << "请输入nums1的元素(nums1必须是nums2的子集,顺序无要求):" << endl;
do {
cin >> startNum1;
nums1.push_back(startNum1);
} while (getchar() != '\n');
Solution s;
vector<int>res = s.nextBiggerNum(nums1, nums2);
system("cls");
cout << "nums1中元素为:";
for (vector<int>::iterator it = nums1.begin(); it != nums1.end(); it++)
{
cout << *it << ", ";
}
cout << endl;
cout << "nums2中元素为:";
for (vector<int>::iterator it = nums2.begin(); it != nums2.end(); it++)
{
cout << *it << ", ";
}
cout << endl;
cout << "nums1对应在nums2中的下一个更大数为:";
for (vector<int>::iterator it = res.begin(); it != res.end(); it++)
{
cout << *it << ", ";
}
cout << endl;
system("pause");
return 0;
}