LeetCode笔记:Weekly Contest 238 比赛记录
Posted 墨客无言
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode笔记:Weekly Contest 238 比赛记录相关的知识,希望对你有一定的参考价值。
0. 赛后总结
因为一些众所周知的原因,这周的比赛实际上是没有参加的,就是在赛后补做了以下题目,然后在这里整理了一下,与君共勉。
1. 题目一
给出题目一的试题链接如下:
1. 解题思路
这一题没啥难度,就是将原数用k进制表达出来然后计算一下每一位的数值之和而已。
2. 代码实现
给出python代码实现如下:
class Solution:
def sumBase(self, n: int, k: int) -> int:
res = 0
while n != 0:
res += n % k
n = n // k
return res
提交代码评测得到:耗时28ms,占用内存14.2MB。
2. 题目二
给出题目二的试题链接如下:
1. 解题思路
这一题的关键点在于数据只能增不能减,因此,我们首先对所有的数字进行一个排序,然后从小到大依次考察每一个数,假设将目标数字定位这个数,那么最小的变换次数一定是将其之前的几个数变为这个数,直到耗尽所有的变换次数,而这可以通过维护一个滑动窗口进行实现。
当窗口向右滑动一位时,需要增加的操作数为(r-l) * (nums[r] - nums[l])
,如果此时操作总数超过额定上限k
,此时需要不断地将左窗口边缘向右滑动,直到所用的操作数不多于k
为止。
这样,我们就可以在 O ( N ) O(N) O(N)的算法复杂度条件下完成求解。
2. 代码实现
给出python代码实现如下:
class Solution:
def maxFrequency(self, nums: List[int], k: int) -> int:
nums = sorted(nums)
l, r, n = 0, 1, len(nums)
res = 1
used = 0
while r < n:
delta = nums[r] - nums[r-1]
used += delta * (r-l)
while l < r and used > k:
used -= nums[r] - nums[l]
l += 1
res = max(res, r-l+1)
r += 1
return res
提交代码评测得到:耗时1184ms,占用内存28.1MB。
3. 题目三
给出题目三的试题链接如下:
1. 解题思路
这一题的思路倒是没啥,由于要求元音字母顺序且必须包含所有的元音字符,因此,我们遇到并非是递增序列的字符就考察前面是否是满足条件的子串,如果是,那么更新最长子串长度。另一方面,如果新的子串以a
开头,那么重新开始计算,否则一直等待直到下一个a
出现。
2. 代码实现
给出python代码实现如下:
class Solution:
def longestBeautifulSubstring(self, word: str) -> int:
is_continuous = False
left = -1
res = 0
seen = set()
for i, c in enumerate(word):
if i == 0:
if c == 'a':
is_continuous = True
left = 0
seen.add(c)
continue
if c >= word[i-1]:
if is_continuous:
seen.add(c)
if len(seen) == 5:
res = max(res, i - left + 1)
else:
is_continuous = False
seen = set()
if c == 'a':
is_continuous = True
left = i
seen.add(c)
return res
提交代码评测得到:耗时852ms,占用内存20.3MB。
不过代码实现不是很优雅就是了。
3. 算法优化
当前最优的算法实现耗时仅76ms,他是直接使用了正则表达式进行的代码实现,给出其代码实现如下:
class Solution:
def longestBeautifulSubstring(self, word: str) -> int:
import re
a = re.findall('a*e*i*o*u*',word)
ans=0
for i in a:
if len(set(i))==5:
ans = max(len(i),ans)
return ans
唉,这个代码比我们的实现实在是好了太多了,惭愧,惭愧……
4. 题目四
给出题目四的试题链接如下:
1. 解题思路
这道题算是半抄半做的吧,自己有点思路,和答案倒也是一致的,但是有一个细节点没想明白,然后看了答案之后修改了一下思路……
这道题的思路就是将所有的限制按照index进行排序,然后如果我们将每一个限制都给到上限,那么就可以求得两个限制位置之间可以达到的最高值为: ( w 2 − w 1 + ∣ h 2 − h 1 ∣ ) / 2 + m i n ( h 1 , h 2 ) (w_2 - w_1 + |h_2 - h_1|) / 2 + min(h_1, h_2) (w2−w1+∣h2−h1∣)/2+min(h1,h2)。
但是这里存在一个前提假设就是所有的限制位置上都是可以达到上限位置的,但是这个实际是没法保证的,因此我们需要对上限的值先进行调整,不过如何调整之前我倒是没有想的很清楚。
答案中给的思路是按照前序和后序分别更新一次,从而确保每一个位置都可以达到,算是非常直接且简洁的一种思路了。
2. 代码实现
我们给出python代码实现如下:
class Solution:
def maxBuilding(self, n: int, restrictions: List[List[int]]) -> int:
restrictions = [[1, 0]] + sorted(restrictions)
if restrictions[-1][0] != n:
restrictions.append([n, n])
m = len(restrictions)
for i in range(1, m):
restrictions[i][1] = min(restrictions[i][1], restrictions[i-1][1] + restrictions[i][0] - restrictions[i-1][0])
for i in range(m-2, -1, -1):
restrictions[i][1] = min(restrictions[i][1], restrictions[i+1][1] + restrictions[i+1][0] - restrictions[i][0])
res = max([x[1] for x in restrictions[:-1]])
for i in range(m-1):
delta = restrictions[i+1][0] - restrictions[i][0] + abs(restrictions[i+1][1] - restrictions[i][1])
res = max(res, delta // 2 + min(restrictions[i+1][1], restrictions[i][1]))
return res
提交代码评测得到:耗时1924ms,占用内存52.6MB。
以上是关于LeetCode笔记:Weekly Contest 238 比赛记录的主要内容,如果未能解决你的问题,请参考以下文章