298场LeetCode周赛

周赛综述&总结:

题目难度:t1(1427)+t2(1646)+t3(1871);

近几周周赛频繁被虐,属实有点打击自信了。前两个题不管怎么说还是用奇奇怪怪的方法给做出来了(这次第二个题感觉还是相对比较难一次AC的,可能需要面向badcase微调一下),第三个题又是直接卡住了,现在复盘来想一想自己的思路在哪里偏了,被题目的case有些迷惑了,然后对于这种数组保留的,有时候正着添加不如反着考虑删除吧;

第一题:小偷了一鸡,直接用 lowerupper 转了一下,如果是其他语言可能会想用一下 'A'-'a' 那类的操作吧;

第二题:思路主要是想 num 减几次那个数字后,能变成一个 mod10 = 0 的数字,这样的话减几次那个数字就变成贪心了,主要一些比较偏的特殊case,面向答案调整下就过了;

第三题:比赛的时候还是没什么思路,现在感觉来说不要被题目的case迷惑住了,对于这种数组保留的有时候要反向着想一想转化成删除的问题。然后这题后来看到别人的思路就是说所有0都是可以被保留的,因为假设存在一种没有保存所有0的情况,那么一定可以用0替换掉一个最高位的1,这样这个数字还会是小于等于k的,只能说这种贪心思路不好想想到也不是很敢写吧;

第四题:咕咕QAQ;

第一题:5242.兼具大小写的最好英文字母【难度:1427】

题目链接

题目大意

给你一个由英文字母组成的字符串 s ,请你找出并返回 s 中的 最好 英文字母。返回的字母必须为大写形式。如果不存在满足条件的字母,则返回一个空字符串。

最好 英文字母的大写和小写形式必须 s 中出现。

英文字母 b 比另一个英文字母 a 更好 的前提是:英文字母表中,ba 之 后 出现。

示例1:

1
2
3
4
输入:s = "lEeTcOdE"
输出:"E"
解释:
字母 'E' 是唯一一个大写和小写形式都出现的字母。

示例2:

1
2
3
4
5
输入:s = "arRAzFif"
输出:"R"
解释:
字母 'R' 是大写和小写形式都出现的最好英文字母。
注意 'A' 和 'F' 的大写和小写形式也都出现了,但是 'R' 比 'F' 和 'A' 更好。

示例3:

1
2
3
4
输入:s = "AbCdEfGhIjK"
输出:""
解释:
不存在大写和小写形式都出现的字母。

提示:

  • 1 <= s.length <= 1000
  • s 由小写和大写英文字母组成

分析和解答

小偷了一鸡,直接用 lowerupper 转了一下,如果是其他语言可能会想用一下 'A'-'a' 那类的操作吧;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution(object):
def greatestLetter(self, s):
"""
:type s: str
:rtype: str
"""

res = []
d = {}
for i in range(len(s)):
d[s[i]] = True

for key, value in d.items():
if d.get(key.upper()) is not None and d.get(key.lower()) is not None:
res += key.upper()

res.sort()
if len(res):
return res[-1]
else:
return ""

第二题:5218.个位数字为 K 的整数之和【难度:1646】

题目链接

题目大意

给你两个整数 numk ,考虑具有以下属性的正整数多重集:

  • 每个整数个位数字都是 k
  • 所有整数之和是 num

返回该多重集的最小大小,如果不存在这样的多重集,返回 -1

注意:

  • 多重集与集合类似,但多重集可以包含多个同一整数,空多重集的和为 0
  • 个位数字 是数字最右边的数位。

示例1:

1
2
3
4
5
6
输入:num = 58, k = 9
输出:2
解释:
多重集 [9,49] 满足题目条件,和为 58 且每个整数的个位数字是 9
另一个满足条件的多重集是 [19,39] 。
可以证明 2 是满足题目条件的多重集的最小长度。

示例2:

1
2
3
输入:num = 37, k = 2
输出:-1
解释:个位数字为 2 的整数无法相加得到 37

示例3:

1
2
3
输入:num = 0, k = 7
输出:0
解释:空多重集的和为 0

提示:

  • 0 <= num <= 3000
  • 0 <= k <= 9

分析和解答

思路主要是想 num 减几次那个数字后,能变成一个 mod10 = 0 的数字,这样的话减几次那个数字就变成贪心了,主要一些比较偏的特殊case,面向答案调整下就过了;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Solution(object):
def minimumNumbers(self, num, k):
"""
:type num: int
:type k: int
:rtype: int
"""

if num == 0:
return 0


if k != 0:
cnt = 0
if num % 10 == 0:
cnt = -1

res = 0
while num > 0:
if num % 10 == 0:
cnt += 1
if cnt == 1:
break
num -= k
res += 1

if num < 0:
return -1
return res

else:
if num % 10 == 0 and num != 0:
return 1
elif num % 10 == 0 and num == 0:
return 0
else:
return -1

第三题:6099.小于等于 K 的最长二进制子序列【难度:1871】

题目链接

题目大意

给你一个二进制字符串 s 和一个正整数 k 。

请你返回 s 的 最长 子序列,且该子序列对应的 二进制 数字小于等于 k 。

注意:

  • 子序列可以有 前导 0 。
  • 空字符串视为 0 。
  • 子序列 是指从一个字符串中删除零个或者多个字符后,不改变顺序得到的剩余字符序列。

示例1:

1
2
3
4
5
输入:s = "1001010", k = 5
输出:5
解释:s 中小于等于 5 的最长子序列是 "00010" ,对应的十进制数字是 2
注意 "00100" 和 "00101" 也是可行的最长子序列,十进制分别对应 4 5
最长子序列的长度为 5 ,所以返回 5

示例2:

1
2
3
4
输入:s = "00101001", k = 1
输出:6
解释:"000001" 是 s 中小于等于 1 的最长子序列,对应的十进制数字是 1
最长子序列的长度为 6 ,所以返回 6

提示:

  • 1 <= s.length <= 1000
  • s[i] 要么是 '0' ,要么是 '1'
  • 1 <= k <= 10^9

分析和解答

比赛的时候还是没什么思路,现在感觉来说不要被题目的case迷惑住了,对于这种数组保留的有时候要反向着想一想转化成删除的问题。然后这题后来看到别人的思路就是说所有0都是可以被保留的,因为假设存在一种没有保存所有0的情况,那么一定可以用0替换掉一个最高位的1,这样这个数字还会是小于等于k的,只能说这种贪心思路不好想想到也不是很敢写吧;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution(object):
def longestSubsequence(self, s, k):
"""
:type s: str
:type k: int
:rtype: int
"""
summ = 0
remove = 0
s = s[::-1]
for i in range(len(s)):
if s[i] == '1':
if summ >= k:
remove += 1
else:
if summ + (1 << i) > k:
remove += 1
summ += (1 << i) # 左移i位置,优先加小位置的

return len(s) - remove

298场LeetCode周赛
http://example.com/2022/06/19/algorithms/leetcode-weekly-contest/298场LeetCode周赛/
作者
Curious;
发布于
2022年6月19日
许可协议