这可能是最简单的一场周赛了,但是却有着灾难级的表现。。。
一、最小偶倍数
给你一个正整数 n ,返回 2 和 n 的最小公倍数(正整数)。
示例 1:
输入: n = 5
输出: 10
解释: 5 和 2 的最小公倍数是 10 。
示例 2:
输入: n = 6
输出: 6
解释: 6 和 2 的最小公倍数是 6 。注意数字会是它自身的倍数。
提示:
1 <= n <= 150
解析
因为其中一个数就是2,就看n是奇数还是偶数就行了 当然,如果另一个数不是2,可以用乘积除以最大公约数的方法
class Solution:
def smallestEvenMultiple(self, n: int) -> int:
if n % 2 == 0:
return n
else:
return n * 2
二、最长的字母序连续子字符串的长度
字母序连续字符串 是由字母表中连续字母组成的字符串。换句话说,字符串 "abcdefghijklmnopqrstuvwxyz" 的任意子字符串都是 字母序连续字符串 。
- 例如,
"abc"是一个字母序连续字符串,而"acb"和"za"不是。
给你一个仅由小写英文字母组成的字符串 s ,返回其 最长 的 字母序连续子字符串 的长度。
示例 1:
输入: s = "abacaba"
输出: 2
解释: 共有 4 个不同的字母序连续子字符串 "a"、"b"、"c" 和 "ab" 。
"ab" 是最长的字母序连续子字符串。
示例 2:
输入: s = "abcde"
输出: 5
解释: "abcde" 是最长的字母序连续子字符串。
提示:
1 <= s.length <= 10^5s由小写英文字母组成
解析
从第二题开始就是灾难级的表现。。。
从字符串s第二个字符逐个遍历,看看当前字符是不是上一个字符的后一个字母就可以了。
class Solution:
def longestContinuousSubstring(self, s: str) -> int:
m = 1
if len(s) == 1:
return 1
res = max(m, 1)
for index, x in enumerate(s[1:]):
if ord(x) == ord(s[index]) + 1:
m += 1
print(m)
else:
res = max(m, res)
m = 1
res = max(m, res)
print(res) # 灾难级表现在这里,因为写了print,第一次提交的时候没写return,导致多了一次错误提交
return res
三、反转二叉树的奇数层
给你一棵 完美 二叉树的根节点 root ,请你反转这棵树中每个 奇数 层的节点值。
- 例如,假设第 3 层的节点值是
[2,1,3,4,7,11,29,18],那么反转后它应该变成[18,29,11,7,4,3,1,2]。
反转后,返回树的根节点。
完美 二叉树需满足:二叉树的所有父节点都有两个子节点,且所有叶子节点都在同一层。
节点的 层数 等于该节点到根节点之间的边数。
示例 1:
输入: root = [2,3,5,8,13,21,34]
输出: [2,5,3,8,13,21,34]
解释:
这棵树只有一个奇数层。
在第 1 层的节点分别是 3、5 ,反转后为 5、3 。
示例 2:
输入: root = [7,13,11]
输出: [7,11,13]
解释:
在第 1 层的节点分别是 13、11 ,反转后为 11、13 。
示例 3:
输入: root = [0,1,2,0,0,0,0,1,1,1,1,2,2,2,2]
输出: [0,2,1,0,0,0,0,2,2,2,2,1,1,1,1]
解释: 奇数层由非零值组成。
在第 1 层的节点分别是 1、2 ,反转后为 2、1 。
在第 3 层的节点分别是 1、1、1、1、2、2、2、2 ,反转后为 2、2、2、2、1、1、1、1 。
提示:
- 树中的节点数目在范围
[1, 2^14]内 0 <= Node.val <= 10^5root是一棵 完美 二叉树
解析
这个输入是一个根节点,要是一个数组,就直接用数学的方法重写一下几个index位置的数值就可以。
回到本题,使用二叉树的层序遍历即可,因为是完美二叉树,难度也降低了一些。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def reverseOddLevels(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
stack = [root]
lay_num = 1
while stack:
lay = []
lay_value = []
for node in stack:
lay_value.append(node.val)
if node.left:
lay.append(node.left)
if node.right:
lay.append(node.right)
lay_num += 1
if lay_num % 2 == 1:
lay_value = lay_value[::-1]
print(lay_value)
for index, node in enumerate(stack):
node.val = lay_value[index] # 灾难表现在这里,定义的TreeNode的值用的是val,而不是value,周赛的时候这里写成了node.value = lay_value[index],调试了四十多分钟,结果一直不对,一直跟原有的树一模一样。。。
stack = lay # 将当前层的节点保留下来,便于下一次遍历
return root
四、字符串的前缀分数和
给你一个长度为 n 的数组 words ,该数组由 非空 字符串组成。
定义字符串 word 的 分数 等于以 word 作为 前缀 的 words[i] 的数目。
- 例如,如果
words = ["a", "ab", "abc", "cab"],那么"ab"的分数是2,因为"ab"是"ab"和"abc"的一个前缀。
返回一个长度为 **n 的数组 **answer **,其中 **answer[i] **是 **words[i] 的每个非空前缀的分数 总和 。
注意: 字符串视作它自身的一个前缀。
示例 1:
输入: words = ["abc","ab","bc","b"]
输出: [5,4,3,2]
解释: 对应每个字符串的答案如下:
- "abc" 有 3 个前缀:"a"、"ab" 和 "abc" 。
- 2 个字符串的前缀为 "a" ,2 个字符串的前缀为 "ab" ,1 个字符串的前缀为 "abc" 。
总计 answer[0] = 2 + 2 + 1 = 5 。
- "ab" 有 2 个前缀:"a" 和 "ab" 。
- 2 个字符串的前缀为 "a" ,2 个字符串的前缀为 "ab" 。
总计 answer[1] = 2 + 2 = 4 。
- "bc" 有 2 个前缀:"b" 和 "bc" 。
- 2 个字符串的前缀为 "b" ,1 个字符串的前缀为 "bc" 。
总计 answer[2] = 2 + 1 = 3 。
- "b" 有 1 个前缀:"b"。
- 2 个字符串的前缀为 "b" 。
总计 answer[3] = 2 。
示例 2:
输入: words = ["abcd"]
输出: [4]
解释:
"abcd" 有 4 个前缀 "a"、"ab"、"abc" 和 "abcd"。
每个前缀的分数都是 1 ,总计 answer[0] = 1 + 1 + 1 + 1 = 4 。
提示:
1 <= words.length <= 10001 <= words[i].length <= 1000words[i]由小写英文字母组成
解析
能看懂题目要求,但是是一个未接触过的数据结构,叫做前缀树,于是参考了一下208. 实现 Trie (前缀树) - 力扣(LeetCode) 这道题的解析,构造了基础的前缀树,同时因为需要计数,出现了多少次,于是给每个字母节点增加一个计数字段。
class Trie:
def __init__(self):
self.children = [None] * 26
self.cnt = 0
def startsWith(self, prefix: str) -> int:
node = self
res = 0
for ch in prefix:
ch = ord(ch) - ord("a")
if not node.children[ch]: # 当找到第一个没有出现的字母,立即停止,第一次提交代码的时候,这里直接跳过了,改成了 if node.children[ch],就会导致计数错误
return res
node = node.children[ch]
res += node.cnt
return res
def insert(self, word: str) -> None:
node = self
for ch in word:
ch = ord(ch) - ord("a")
if not node.children[ch]:
node.children[ch] = Trie()
node = node.children[ch]
node.cnt += 1
# print("insert %s %s %s" % (word, ch, node.cnt)) # print的内容过多,也会导致提交失败,超出长度限制了
class Solution:
def sumPrefixScores(self, words: List[str]) -> List[int]:
trie = Trie()
for word in words:
trie.insert(word)
res = []
for word in words:
res.append(trie.startsWith(word))
# print(res)
return res