力扣:数组(一)

这里写自定义目录标题

  • 数组遍历
  • 485: 最大连续1的个数
    • 解题思路
    • 实现代码
  • 495: 提莫攻击
    • 解题思路
    • 实现代码
  • 414: 第三大的数
    • 解题思路
    • 实现代码
  • 628:三个数的最大乘积
    • 解题思路
    • 实现代码

数组遍历

力扣题目编号,数组的遍历:485、495、414、628

485: 最大连续1的个数

    给定一个二进制数组, 计算其中最大连续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;
    }
};

495: 提莫攻击

    在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄,他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态。现在,给出提莫对艾希的攻击时间序列和提莫攻击的中毒持续时间,你需要输出艾希的中毒状态总时长。

    你可以认为提莫在给定的时间点进行攻击,并立即使艾希处于中毒状态。

示例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;
    }
};

414: 第三大的数

    给定一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。要求算法时间复杂度必须是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;
    }
};

628:三个数的最大乘积

    给定一个整型数组,在数组中找出由三个数组成的最大乘积,并输出这个乘积。

示例 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)希尔排序,成功解决。

力扣:数组(一)_第1张图片

实现代码

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);
        } 
    }
};

你可能感兴趣的:(力扣,c++,leetcode)