力扣题目编号,数组的遍历:485、495、414、628
给定一个二进制数组, 计算其中最大连续1的个数。
示例 1:
输入: [1,1,0,1,1,1]
输出: 3
解释: 开头的两位和最后的三位都是连续1,所以最大连续1的个数是 3.
注意:
输入的数组只包含 0 和1。
输入数组的长度是正整数,且不超过 10,000。
定义两个count用于存储连续个数,一个是当前连续个数,一个为当前最大连续个数。
遍历数组,判断该元素是否为1,若为1,则count++;不为1,则使用count比较max_count,若count>max_count,则ma_count=count;反之则不用管max_count。并且把count置零。
最后如果数组单一的话,需要重新对count和max_count进行比较
class Solution {
public:
int findMaxConsecutiveOnes(vector<int>& nums) {
int count = 0;
int max_count = 0;
for(int i = 0 ;i < nums.size() ; i++)
{
if (nums[i]==1)
{
count=count+1;
}
else
{
if (count>max_count)
{
max_count=count;
}
count=0;
}
}
if (count>max_count)
{
max_count=count;
}
return max_count;
}
};
在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄,他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态。现在,给出提莫对艾希的攻击时间序列和提莫攻击的中毒持续时间,你需要输出艾希的中毒状态总时长。
你可以认为提莫在给定的时间点进行攻击,并立即使艾希处于中毒状态。
示例1:
输入: [1,4], 2
输出: 4
原因: 第 1 秒初,提莫开始对艾希进行攻击并使其立即中毒。中毒状态会维持 2 秒钟,直到第 2 秒末结束。
第 4 秒初,提莫再次攻击艾希,使得艾希获得另外 2 秒中毒时间。
所以最终输出 4 秒。
示例2:
输入: [1,2], 2
输出: 3
原因: 第 1 秒初,提莫开始对艾希进行攻击并使其立即中毒。中毒状态会维持 2 秒钟,直到第 2 秒末结束。
但是第 2 秒初,提莫再次攻击了已经处于中毒状态的艾希。
由于中毒状态不可叠加,提莫在第 2 秒初的这次攻击会在第 3 秒末结束。
所以最终输出 3 。
首先需要判断的是,当前数组元素+持续时间,是否大于下一个数组元素,如果大于,说明中毒时间只作用在两者时间内,如果超过,则中毒时间等于持续时间。
最后还要判断当数组为空,或者持续时间为0时的特殊情况。
class Solution {
public:
int findPoisonedDuration(vector<int>& timeSeries, int duration) {
int time = 0;
if(timeSeries.size() == 0) {
return time;
}
if(duration == 0) {
return time;
}
for(int i = 0 ; i < timeSeries.size()-1 ; i ++)
{
if (timeSeries[i]+duration<=timeSeries[i+1])
{
time=time+duration;
}
else
{
time=time+(timeSeries[i+1]-timeSeries[i]);
}
}
time=time+duration;
return time;
}
};
给定一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。要求算法时间复杂度必须是O(n)。
示例 1:
输入: [3, 2, 1]
输出: 1
解释: 第三大的数是 1.
示例 2:
输入: [1, 2]
输出: 2
解释: 第三大的数不存在, 所以返回最大的数 2 .
示例 3:
输入: [2, 2, 3, 1]
输出: 1
解释: 注意,要求返回第三大的数,是指第三大且唯一出现的数。
存在两个值为2的数,它们都排第二。
首先定义最大,第二大,第三大的值为int_min,还需要定义一个标志位用来判断是否有第三大的数。
第一步,先找到最大值
第二步,数组元素不等于最大值,找到第二大的值
第三步,数组元素不等于最大值也不等于第二大的值,找到第三大值市,把标志位置为1
第四步,判断标志位是否为1,若为1,则返回第三大值,反之返回最大值
class Solution {
public:
int thirdMax(vector<int>& nums) {
int max = INT_MIN;
int sec_max = INT_MIN;
int thi_max = INT_MIN;
int cnt=0;
//找出最大值
for(int i = 0 ;i < nums.size() ; i++)
{
if(nums[i] > max)
max = nums[i];
}
//找出第二大的值
for(int i = 0 ;i < nums.size() ; i++)
{
if(nums[i] != max) {
if(nums[i] > sec_max)
sec_max = nums[i];
}
}
//找出第三大的值
for(int i = 0 ;i < nums.size() ; i++) {
if(nums[i] != max && nums[i] != sec_max) {
if(nums[i] > thi_max)
thi_max = nums[i];
//记录是都有第三大的标志位
cnt++;
}
}
//如果没有第三大的数,就返回最大值
if(cnt==0)
{
return max;
}
return thi_max;
}
};
给定一个整型数组,在数组中找出由三个数组成的最大乘积,并输出这个乘积。
示例 1:
输入: [1,2,3]
输出: 6
示例 2:
输入: [1,2,3,4]
输出: 24
注意:
给定的整型数组长度范围是[3,104],数组中所有的元素范围是[-1000, 1000]。
输入的数组中任意三个数的乘积不会超出32位有符号整数的范围。
最初的想法是 跟找出第三大的数解法一致,先遍历找出最大的数,再找出第二大的数,再找出第三大的数,后来发现如果最小的两个数为负数,比如数组[-20,-17,0,10,12,14],我们得到的结果与预期结果不一致。
改进的思路,首先对数组进行排序,十大经典排序,哪个都行。排序结束后得到一个有序的数组,然后对nums[0]*nums[1]与nums[n-2]*nums[n-3]进行比较,较大的一方乘nums[n-1],即可得出结果。
在实际情况中还遇到了超出时间的限制,最后解决:把O(n2)的冒泡排序改进为O(nlog2n)希尔排序,成功解决。
class Solution {
public:
int maximumProduct(vector<int>& nums) {
int n = nums.size();
int temp = n / 2;
int gap = n / 2;
while (gap > 0)
{
for (int i = gap; i < n; i++)
{
temp = nums[i];
int preIndex = i - gap;
while (preIndex >= 0 && nums[preIndex] > temp)
{
nums[preIndex + gap] = nums[preIndex];
preIndex -= gap;
}
nums[preIndex + gap] = temp;
}
gap /= 2;
}
int t1=nums[0]*nums[1];
int t2 = nums[n-2]*nums[n-3];
if(t1>t2)
{
return (t1*nums[n-1]);
}
else
{
return (nums[n-1]*t2);
}
}
};