力扣刷题之路-----数组的遍历

参考刷题顺序:力扣刷题顺序

本文章做自我总结,总结做题时自己的想法以及官方解题思路。

485 最大连续 1 的个数

485
是个非常简单的题,也就没啥可说的了。放个代码意思意思。

class Solution {
    public int findMaxConsecutiveOnes(int[] nums) {
        int time = 0;
        int max = 0;
        for(int i = 0;i<nums.length;i++){
            if(nums[i] == 1){
                time++;
                if(max<=time){
                    max = time;
                }
            }
            else {

                time = 0;
            }
        }
        return max;
    }
}

495 提莫攻击

题目485
自己的想法
这个题目确实想了比较多,一直想要找一个规律可以直接算出来几种情况的结果。本来想的是开始和结束的时间可以走一些小捷径。后来发现想的太复杂了。这道题主要是靠着画图想出来的,和小时候的数学归纳法一样。感觉还是要先从简单的想法出发,最简单的想法或许才是最好的。
分为两种情况:一是(开始攻击时间+攻击时长)<=下次开始攻击时间,即第二次攻击的时候,上一次攻击已经结束,这种情况下攻击时长直接+;二是上次攻击还没有结束,如图。第二次攻击多出来的时长是2-1。多画几种情况也是一样的。
第二种情况

class Solution {
    public int findPoisonedDuration(int[] timeSeries, int duration) {
        int time=duration;
        for(int i=0;i<timeSeries.length-1;i++){
            if(timeSeries[i]+duration <= timeSeries[i+1]){
                time+=duration;
            }
            else{
                time+=timeSeries[i+1]-timeSeries[i];
            }
        }
        return time;
    }
}

官方的思想
看了看官方的解题思路是一样的,但是代码不一样。

class Solution {
    public int findPoisonedDuration(int[] timeSeries, int duration) {
        int n = timeSeries.length;
        if (n == 0) return 0;

        int total = 0;
        for(int i = 0; i < n - 1; ++i)
          total += Math.min(timeSeries[i + 1] - timeSeries[i], duration);
        return total + duration;
    }
}

作者:LeetCode
链接:https://leetcode-cn.com/problems/teemo-attacking/solution/ti-mo-gong-ji-by-leetcode/
来源:力扣(LeetCode)

414 第三大的数

414
自己的想法
想的太复杂了。先把数组的数都放到一个集合里,然后再放到list里,排个序。最后list的长度大于等于3,输出第三个数;否则输出最大的数。光看这个想法都能知道这个算法的时间空间复杂度都非常大。

class Solution {
    public int thirdMax(int[] nums) {
        int n = nums.length;
        List temp = new LinkedList();
        Set changes = new HashSet();
        for(int i=0;i<n;i++){
            changes.add(nums[i]);
        }
        for(Object change:changes){
            temp.add(change);
        }
        temp.sort(Comparator.reverseOrder());
        if(temp.size()>=3){
            return temp.get(2).hashCode();
        }
        else return temp.get(0).hashCode();
    }
}

官方的想法
首先是有序集合的方法,利用TreeSet来存储数。集合的长度大于3的时候删除最小的,可以保证最小的永远是第三大的。学到了有序集合这个做法。

class Solution {
    public int thirdMax(int[] nums) {
        TreeSet<Integer> s = new TreeSet<Integer>();
        for (int num : nums) {
            s.add(num);
            if (s.size() > 3) {
                s.remove(s.first());
            }
        }
        return s.size() == 3 ? s.first() : s.last();
    }
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/third-maximum-number/solution/di-san-da-de-shu-by-leetcode-solution-h3sp/
来源:力扣(LeetCode)

另外一种方法是设置三个数first,second,third分别表示第一大,第二大以及第三大的数。遍历一遍数组,遍历过程中对这三个标志数进行变化。刚开始的时候把三个数都设置成比数组值最小值还小的数,如果third变化了,则输出third,否则输出first。

    public void thinkTest(){
        long INF = (long)Math.pow(-2,31)-1;
        int nums[] = {1,3,2,2};
        long first,second,third;
        first=second=third=INF;
        int n = nums.length;
        for(int i=0;i<n;i++){
            if(nums[i]>first){
                third=second;
                second=first;
                first=nums[i];
            }
            if(nums[i]>second && nums[i]<first){
                third=second;
                second=nums[i];
            }
            if(nums[i]>third && nums[i]<second ){
                third=nums[i];
            }

        }
        if(third!=INF){
            System.out.println(third);
        }
        else System.out.println(first);
    }

628 三个数的最大乘积

628
自己的想法:
被这个题卡了好久。本来想的是按照绝对值进行排序,然后发现总是找不到一个规律。后来实在是想不到,看了官方解题思路。直接按照大小排序,分成三种情况:全正,全负,有正有负。这三种情况下的最终结果都是三个最大的乘积或者一个最大和两个最小的乘积。果然还是要静下心来,不要着急,写下来。

    public void mytest(){
        int[] nums = {-100,-2,-3,1};
        int n=nums.length;
        int max;
        for(int i=0;i<n-1;i++){
            max=nums[i];
            for(int j = i+1;j<n;j++){
                if(max< nums[j]){
                    int temp;
                    temp=max;
                    max = nums[j];
                    nums[j]=temp;
                }
            }
            nums[i] = max;
        }
        System.out.println(Math.max(nums[0]*nums[1]*nums[2],nums[0]*nums[n-1]*nums[n-2]));
    }

看了题解思路自己写的代码。然后看了看官方的代码,好简单!学习了!
官方的想法:

class Solution {
    public int maximumProduct(int[] nums) {
        Arrays.sort(nums);
        int n = nums.length;
        return Math.max(nums[0] * nums[1] * nums[n - 1], nums[n - 3] * nums[n - 2] * nums[n - 1]);
    }
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/maximum-product-of-three-numbers/solution/san-ge-shu-de-zui-da-cheng-ji-by-leetcod-t9sb/
来源:力扣(LeetCode)

另一种方法和414差不多。因为所涉及的只有前三大的数以及两最小的数。找出来这几个数就可以。

class Solution {
public:
    int maximumProduct(vector<int>& nums) {
        // 最小的和第二小的
        int min1 = INT_MAX, min2 = INT_MAX;
        // 最大的、第二大的和第三大的
        int max1 = INT_MIN, max2 = INT_MIN, max3 = INT_MIN;

        for (int x: nums) {
            if (x < min1) {
                min2 = min1;
                min1 = x;
            } else if (x < min2) {
                min2 = x;
            }

            if (x > max1) {
                max3 = max2;
                max2 = max1;
                max1 = x;
            } else if (x > max2) {
                max3 = max2;
                max2 = x;
            } else if (x > max3) {
                max3 = x;
            }
        }

        return max(min1 * min2 * max1, max1 * max2 * max3);
    }
};

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/maximum-product-of-three-numbers/solution/san-ge-shu-de-zui-da-cheng-ji-by-leetcod-t9sb/
来源:力扣(LeetCode)

总结:
数组的遍历这几道题都不难。发现有些时候使用if语句可以变为使用max方法,好像是更方便一点,以后做题的时候可以学习。另外做题的时候要静下心来,一味的在脑子里想是想不出来的,需要拿起笔来写一写。也不能总想着一口吃成胖子,需要从最简单的开始想,或许最简单的才是最好的。

posted @ 2022-05-03 21:28  啵啵ray  阅读(26)  评论(0编辑  收藏  举报