给出题目一的试题链接如下:
这一题还蛮直接的,用python的内置split函数即可进行处理。
给出python代码实现如下:
class Solution:
def splitWordsBySeparator(self, words: List[str], separator: str) -> List[str]:
res = []
for w in words:
res.extend([token for token in w.split(separator) if token != ""])
return res
提交代码评测得到:耗时126ms,占用内存16.5MB。
给出题目二的试题链接如下:
这一题的思路上其实也挺直接的,相当于就是一个倒序的有序数组,从后往前,如果满足合并条件,就将数字进行合并,直到无法合并时,就更新下一个需要操作的数字。
由此,我们就能够得到最终的一系列数字,然后我们返回最大值即可。
给出python代码实现如下:
class Solution:
def maxArrayValue(self, nums: List[int]) -> int:
res = 0
n = len(nums)
prev = nums[-1]
for i in range(n-2, -1, -1):
if nums[i] <= prev:
prev += nums[i]
else:
res = max(res, prev)
prev = nums[i]
res = max(res, prev)
return res
提交代码评测得到:耗时917ms,占用内存31MB。
给出题目三的试题链接如下:
这一题思路上来说我用的是二分法,就是通过二分的方式找到最大的可以找到构造方式的group数目即可。
从而,问题就变成了,给出group数目 k k k,如何判断能否成功分割。
我们选择usageLimits最大的 k k k个数字进行基底,然后考察能否进行分配。此时,剩余的数字的usageLimits就可以全部用来做冗余数进行填补。
然后,我们从usageLimits排序小到大进行考察,分别从大到小填充各个group,比如说,第 i i i大的值就填充 i i i个group,然后多余的就可以全部添加到冗余当中,由于本身usageLimits是从小到大排列的,因此不可能出现被视为冗余的元素被重复填充到了同一个group当中,因为后者的元素个数一定被前者多,所以前者能够被填充到某一个group那么后者一定也能够被填充到某一个group当中。
由此,我们只需要判断是否可以完成填充即可,如果某一次无法成功填充,那么就一定无法成功分配,反之即可成功分配到 k k k个group当中。
给出python代码实现如下:
class Solution:
def maxIncreasingGroups(self, usageLimits: List[int]) -> int:
n = len(usageLimits)
usageLimits = sorted(usageLimits, reverse=True)
accums = [0] + list(accumulate(usageLimits))
def can_split(k):
remain = accums[-1] - accums[k]
for i in range(k):
need = i+1
idx = k-1-i
if need > usageLimits[idx] + remain:
return False
if usageLimits[idx] > need:
remain += min(k-need, usageLimits[idx] - need)
else:
remain -= need - usageLimits[idx]
return True
i, j = 1, n+1
while j-i>1:
k = (i+j) // 2
if can_split(k):
i = k
else:
j = k
return i
提交代码评测得到:耗时2520ms,占用内存32MB。
给出题目四的试题链接如下:
这一题思路上来说个人还是觉得有点巧妙的。
具体来说,我们可以通过一个遍历给出每一个点从根节点到他们的路径,这个是不难实现的。然后,我们就可以将每一个点用他们的路径来进行表达。
此时,如果存在某两个点 u , v u, v u,v,他们之间的路径可以构成一个回文,那么显然从根节点到这两个点的路径的concat必然也能够构成一个回文,因为他们之间如果存在有重复的路径,那么这条路径一定被走了两遍,对回文的构造不会产生任何影响。
基于这个思路,我们就可以对这个问题进行解答。
显然,要构成回文字符串,那么当且仅当两条路径合在一起时最多只有一个字符的个数为奇数,因此,事实上我们只需要考察每一个点所代表的路径当中26个字母的奇偶性即可,因此,我们事实上可以只考虑奇偶性用一个26位的数字来替换掉完整的路径,此时我们便可以优化回文的判断。
此时,对于任何一个节点,其对应的路径假设为 v v v,我们只需要考察:
当然,考虑到路径的唯一性,我们事实上还需要进行去重处理,不过也不是什么大事就是了。
给出python代码实现如下:
class Solution:
def countPalindromePaths(self, parent: List[int], s: str) -> int:
children = defaultdict(list)
for i, p in enumerate(parent):
children[p].append(i)
cnt = defaultdict(int)
q = [(0, 0)]
while q != []:
p, v = q.pop(0)
cnt[v] += 1
for c in children[p]:
r = s[c]
q.append((c, v ^ (1 << (ord(r) - ord('a')))))
res = 0
keys = list(cnt.keys())
for k in keys:
v = cnt[k]
res += v * (v-1)
for i in range(26):
res += v * cnt[k ^ (1 << i)]
return res // 2
提交代码评测得到:耗时2225ms,占用内存153.7MB。