10.25号上午在leetcode上参加了「猿辅导」&「力扣」举办的第212场周赛,也是本菜鸡第一次参加leetcode周赛(希望不会是最后一场,哈哈)
一共4道题,时限是1小时30分钟
最后只做出了前2道,后面2道题,我根本看不懂。。。
不过唯一欣慰的是,这次做题没有参考任何东西,完全是靠自己想出来的,而且都是提交一次就通过了,不容易,值得记录下来
题目1
描述:
LeetCode 设计了一款新式键盘,正在测试其可用性。测试人员将会点击一系列键(总计 n 个),每次一个。
给你一个长度为 n 的字符串 keysPressed ,其中 keysPressed[i] 表示测试序列中第 i 个被按下的键。releaseTimes 是一个升序排列的列表,其中 releaseTimes[i] 表示松开第 i 个键的时间。字符串和数组的 下标都从 0 开始 。第 0 个键在时间为 0 时被按下,接下来每个键都 恰好 在前一个键松开时被按下。
测试人员想要找出按键 持续时间最长 的键。第 i 次按键的持续时间为 releaseTimes[i] - releaseTimes[i - 1] ,第 0 次按键的持续时间为 releaseTimes[0] 。
注意,测试期间,同一个键可以在不同时刻被多次按下,而每次的持续时间都可能不同。
请返回按键 持续时间最长 的键,如果有多个这样的键,则返回 按字母顺序排列最大 的那个键。
示例 1:
输入:releaseTimes = [9,29,49,50], keysPressed = "cbcd"
输出:"c"
解释:按键顺序和持续时间如下:
按下 'c' ,持续时间 9(时间 0 按下,时间 9 松开)
按下 'b' ,持续时间 29 - 9 = 20(松开上一个键的时间 9 按下,时间 29 松开)
按下 'c' ,持续时间 49 - 29 = 20(松开上一个键的时间 29 按下,时间 49 松开)
按下 'd' ,持续时间 50 - 49 = 1(松开上一个键的时间 49 按下,时间 50 松开)
按键持续时间最长的键是 'b' 和 'c'(第二次按下时),持续时间都是 20
'c' 按字母顺序排列比 'b' 大,所以答案是 'c'
示例 2:
输入:releaseTimes = [12,23,36,46,62], keysPressed = "spuda"
输出:"a"
解释:按键顺序和持续时间如下:
按下 's' ,持续时间 12
按下 'p' ,持续时间 23 - 12 = 11
按下 'u' ,持续时间 36 - 23 = 13
按下 'd' ,持续时间 46 - 36 = 10
按下 'a' ,持续时间 62 - 46 = 16
按键持续时间最长的键是 'a' ,持续时间 16
原题链接:https://leetcode-cn.com/problems/slowest-key/
我的思路:
这个我想的比较直白,先把每个按键的时间都拿到,存到一个列表A中;
然后从这个列表中找出最大的那个;
再定义一个列表B,把最大值依次与A中的元素对比,找出最大值所在的位置,并把这些位置存到B中;
再定义一个列表C,从按键字符中提取出时间最大值对应位置的元素,放到C中;
把C中的元素倒叙排列,返回第一个元素即可
代码如下:
class Solution(object): def slowestKey(self, releaseTimes, keysPressed): """ :type releaseTimes: List[int] :type keysPressed: str :rty """ tm = [] for t in range(len(releaseTimes)): if t ==0: tm.append(releaseTimes[0]) else: tm.append(releaseTimes[t]-releaseTimes[t-1]) max_time = max(tm) inde = [] for i in range(len(tm)): if tm[i] == max_time: inde.append(i) temp = [] for j in inde: temp.append(keysPressed[j]) temp.sort() temp.reverse() return temp[0]
题目2:等差子数组
描述:
如果一个数列由至少两个元素组成,且每两个连续元素之间的差值都相同,那么这个序列就是 等差数列 。更正式地,数列 s
是等差数列,只需要满足:对于每个有效的 i
, s[i+1] - s[i] == s[1] - s[0]
都成立。
例如,下面这些都是 等差数列 :
1, 3, 5, 7, 9 7, 7, 7, 7 3, -1, -5, -9
下面的数列 不是等差数列 :
1, 1, 2, 5, 7
给你一个由 n
个整数组成的数组 nums
,和两个由 m
个整数组成的数组 l
和 r
,后两个数组表示 m
组范围查询,其中第 i
个查询对应范围 [l[i], r[i]]
。所有数组的下标都是 从 0 开始 的。
返回 boolean
元素构成的答案列表 answer
。如果子数组 nums[l[i]], nums[l[i]+1], ... , nums[r[i]]
可以 重新排列 形成 等差数列 ,answer[i]
的值就是 true
;否则answer[i]
的值就是 false
。
示例 1:
输入:nums =[4,6,5,9,3,7]
, l =[0,0,2]
, r =[2,3,5]
输出:[true,false,true]
解释: 第 0 个查询,对应子数组 [4,6,5] 。可以重新排列为等差数列 [6,5,4] 。 第 1 个查询,对应子数组 [4,6,5,9] 。无法重新排列形成等差数列。 第 2 个查询,对应子数组[5,9,3,7] 。
可以重新排列为等差数列[3,5,7,9] 。
示例 2:
输入:nums = [-12,-9,-3,-12,-6,15,20,-25,-20,-15,-10], l = [0,1,6,4,8,7], r = [4,4,9,7,9,10] 输出:[false,true,false,false,true,true]
原题链接:https://leetcode-cn.com/contest/weekly-contest-212/problems/arithmetic-subarrays/
我的思路:
1、首先反复读了几遍题目和给出的示例,终于搞懂了题目的要求
第i个查询,这里i大小是由数组l或r的长度确定,如果数组长度是3,那么i=0,1,2;
nums的子数组是否可重新排列为等差数列:这个子数组的范围是根据l[i]和r[i]确定,例如示例1中第2个查询,对应的l[2]=2,r[2]=5,所以子数组的范围就是nums[2]~nums[5];
然后判断这个子数组经过重组后能否形成等差数列,注意⚠️:可以重新排列(有些子数组乍一看不是等差的,但是按顺序重新排列后就是等差的了);
最后根据要求,返回每个子数组的布尔值即可
2、搞懂题目要求后,想一下该如何实现
这里我能想到的最直白的方式就是用for循环来遍历nums了
因为要判断每个子数组是否为等差数列,所以先定义了一个方法,这个方法的作用就是判断一个数组是否为等差数列;
第一个for循环,用来确定需要判断多少个子数组是否为等差数列;
第二个for循环,用来提取nums中的元素,组成数列;
最终的代码如下
class Solution(object): def checkArithmeticSubarrays(self, nums, l, r): """ :type nums: List[int] :type l: List[int] :type r: List[int] :rtype: List[bool] """ v = [] for i in range(len(l)): temp = [] for t in range(l[i], r[i]+1): temp.append(nums[t]) v.append(self.new(temp)) return v def new(self, n): x = [] n.sort() for j in range(len(n)-1): if n[j + 1] - n[j] == n[1] - n[0]: x.append(True) else: x.append(False) if False in x: return False else: return True
虽然2道题的解法笨是笨了些,不过最终都运行通过了
结束后,看了看其他人的答案,感叹人家是咋想的,写得又快有精致