前言
第 278 场周赛是Leetcode上2021年最后一场周赛,也是我第一次参加的周赛,第一道题秒了,然后可能是自己肚子疼吧,第二题写完一直有bug,死活找不出来,一直被卡住。直到比赛结束后,吃完午饭,一下子就找到了bug,最后属实是把自己气笑了。
以后尽量每场周赛都会参加的,再接再厉,2022加油!
5993. 将找到的值乘以 2
第 278 场周赛第一题,是个简单题
题目展示
题意解读
这个题目比较简单,题目意思是让我们在数组nums中找original这个数,找到之后把original翻倍继续找,直到找不到翻倍的数字为止。
解题思路
我们每次找到original之后都要把original翻倍,那么我们每次需要找的数字只会越来越大。
那么我们可以先给数组进行排序。在排序之后,每次在找到original之后,对于新的original如果存在的话,就肯定在数组中当前位置的后面,我们只需要接着往下找就行了,不需要回头再重新开始遍历数组了。
思路有了,那我们就来实现代码吧!
代码实现
class Solution { public int findFinalValue(int[] nums, int original) { Arrays.sort(nums); for(int i:nums){ if(i==original){ original*=2; } } return original; } }
执行结果
5981. 分组得分最高的所有下标
第 278 场周赛第二题,是个中等
题目展示
题目解读
给你一个数组,数组中元素不是1就是0,然后让我们把数组分成左右两部分。分法是按照数组的下标分,也包括i=0和i=n,即从数组任意两个元素之间包括第一个元素之前和最后一个元素之后。在分成两部分最后总计左半部分的0和右半部分的1的总数,并且记录下总数最大时候是在数组下标多少分的。有可能这个总数最大时候分法不唯一,所以最后以List形式返回。
解题思路
看到这个题,你可能会想建立两层循环,外层循环是每次分割数组的位置,内层循环是用来统计1与0总数的,然后在用哈希表来保存对应次数的分割位置,然后找到最大的key值,返回对应的value组成的list。听起来行如流水,一气呵成。
但是,并不可行。因为数组长度最大是可以到100000的,会超时的。(其实第一次就是这样写的,呜呜呜)
那我们换个思路在时间复杂度为O(n)时候解决掉。
我们是要知道每个分割位置的左边的0数与右边的1数之和分别是多少然后统计出最大的值所对应的所有下标的。
这个步骤其实我们在时间复杂度为O(n)内就可以解决。
我们先设立一个大小为数组nums大小加1的数组用来保存,每个分割位置所对应左0右1数总和。
我们先统计出来每个分割位置右边1的个数,这个我们使用一次循环就可以解决掉了。
知道右边1的数了,还差左边0的个数,那我们在进行一次遍历数组即可:
当nums数组当前位置为0的时候,那么以这个数字后面的这个分割位置对应的总数相比于前一个分割位置的总数就得加1
当nums数组当前位置为1的时候,那么以这个数字后面的这个分割位置对应的总数相比于前一个分割位置的总数就得减1
在这个过程中比较记录最大的总数是多少。
做后再遍历一遍记录的数组,把所有等于最大记录数字的下标保存在list中去。
思路ok了,我们接下来用代码来实现一下。
代码实现
class Solution { public List maxScoreIndices(int[] nums) { int len=nums.length; int[] ar = new int[len+1]; for(int i : nums){ if(i==1) ar[0]++; } int max = ar[0]; for(int i=1 ;i<=len;i++){ if(nums[i-1]==0) ar[i]=ar[i-1]+1; else ar[i]=ar[i-1]-1; if(ar[i]>max) max=ar[i]; } List list= new ArrayList(); for(int i=0 ;i if(ar[i]==max){ list.add(i); } } return list; } }
执行结果
结语
后两个题不会,哈哈哈