Leetcode Contest 28
今晚吃的是烤鱼以及手撕鸡。
这次的比赛让我开始怀疑自己的智商了。
第一题Student Attendance Record I
简单的字符串处理。
class Solution(object):
def checkRecord(self, s):
"""
:type s: str
:rtype: bool
"""
a = 0
for c in s:
if c == 'A':
a += 1
if a > 1:
return False
if s.find('LLL') != -1:
return False
return True
第二题Optimal Division
我的做法相当蠢!我是用dfs枚举所有可能加括号的式子,从中挑出最大的。但是其实不用这么麻烦,这个题目是有公式的:如果数组长度小于3,那么不加括号直接返回。如果长度大于等于3,假设数组为[a0, a1, ..., an-1],那么只加一个括号返回
我那愚蠢的代码:
class Solution(object):
def optimalDivision(self, nums):
"""
:type nums: List[int]
:rtype: str
"""
def dfs(cur):
if len(cur) == 1:
yield cur[0], str(cur[0])
elif len(cur) == 2:
yield float(cur[0])/cur[1], '{}/{}'.format(cur[0], cur[1])
else:
x = float(cur[0])
for n in cur[1:]:
x /= n
s = '/'.join(map(str, cur))
yield x, s
for i in xrange(1, len(cur)):
left = cur[:i]
right = cur[i:]
for xl, sl in dfs(left):
for xr, sr in dfs(right):
x = float(xl) / float(xr)
if len(left) > 1:
sl = '({})'.format(sl)
if len(right) > 1:
sr = '({})'.format(sr)
s = '{}/{}'.format(sl, sr)
yield x, s
ans = ''
m = 0.0
for x, s in dfs(nums):
if x > m:
m = x
ans = s
return ans
小伙伴机智的想法:
class Solution(object):
def optimalDivision(self, nums):
"""
:type nums: List[int]
:rtype: str
"""
if len(nums) == 1:
return str(nums[0])
elif len(nums) == 2:
return '{}/{}'.format(nums[0], nums[1])
else:
return '{}/({})'.format(nums[0], '/'.join(map(str, nums[1:])))
第三题Split Assembled Strings
这题我想了挺久的,也是最后做的一道题。我的想法是生成所有可能的字符串,然后挑出最大的。这里有两个优化。第一个优化是先找出最大的字符,那么我们只需要考虑以该字符开始的字符串。第二个优化是对字符串数组strs做一个预处理:strs[i] = max(strs[i], reverse(strs[i])),这样的话我们可以快速展开字符串组成的圈。
class Solution(object):
def splitLoopedString(self, strs):
"""
:type strs: List[str]
:rtype: str
"""
pool = []
for i, s in enumerate(strs):
strs[i] = max(s, s[::-1])
def to_right(s, i, j):
ans = s[j:]
for k in xrange(1, len(strs)):
t = (i+k) % len(strs)
ans += strs[t]
ans += s[:j]
return ans
mc = max(''.join(strs))
for i, s in enumerate(strs):
for j, c in enumerate(s):
if c == mc:
pool.append(to_right(s, i, j))
s = s[::-1]
for j, c in enumerate(s):
if c == mc:
pool.append(to_right(s, i, j))
return max(pool)
第四题Student Attendance Record II
我的想法:首先考虑没有A的情况。用f(n)表示没有A的情况下满足第一题条件字符串数目。那么很简单的我们有如下递归式子:
对于有A的情况,因为我们知道A只能有一个,所以我们可以枚举A的位置,得到有A的字符串数目S:
那么答案就是f(n) + S。
class Solution(object):
def checkRecord(self, n):
"""
:type n: int
:rtype: int
"""
f = [0] * max((n+1), 4)
f[0] = 1
f[1] = 2
f[2] = 4
f[3] = 7
for i in xrange(4, n+1):
f[i] = (f[i-1]+f[i-2]+f[i-3]) % (10**9+7)
ans = f[n]
for i in xrange(n):
ans = (ans + f[i] * f[n-1-i]) % (10**9+7)
return ans
我的做法是需要O(n)的空间的。我那机智的小伙伴们是同时考虑A,L和P的,这样会有6种状态。他们写出了状态转移方程,只需用到O(1)的空间。