目录
11盛最多水的容器
class Solution:
def maxArea(self, height: List[int]) -> int:
s, e= 0, len(height)-1
v = (e-s)*min(height[s],height[e])
while e-s>1:
# 挑短边往前走
if height[s] < height[e]:
s +=1
else:
e -=1
v = max((e-s)*min(height[s],height[e]), v)
return v
12整数转罗马数字
class Solution:
def intToRoman(self, num: int) -> str:
res = ''
for f in [1000, 100, 10, 1]:
res = res + self.unit(f, num//f)
num -= num//f*f
return res
def unit(self, loc=1, val=0) -> str:
dic = {1:['I','V','X'], 10:['X','L','C'], 100:['C','D','M'], 1000:['M','?','?']}
cur = dic[loc] # 确认在第几位
# 按位遍历
if val == 0: return ''
elif val == 4: return cur[0]+cur[1]
elif val == 5: return cur[1]
elif val == 9: return cur[0]+cur[2]
if val>5: return cur[1]+cur[0]*(val-5)
else: return cur[0]*val
13罗马数字转整数
class Solution:
def romanToInt(self, s: str) -> int:
res = 0
for f in [1000, 100, 10, 1]:
val, num = self.unit(f, s)
res += val*f
s = s[num:]
return res
def unit(self, loc=1, ss=''):
dic = {1:['I','V','X'], 10:['X','L','C'], 100:['C','D','M'], 1000:['M','#','#']}
cur = dic[loc]
# 向前处理:按位翻译,十位上的情况分为:11-X+I, 41-XL+I, 51-LI, 71-LXX+I, 91-XM+I——>开头都是X、L
# 还要排除特殊情况会出现XL:9-IX
if len(ss)>0 and ss[0] in cur[:-1]:
# X开头的3种情况
if ss[:2] == ''+cur[0]+cur[2]: return 9,2 # 匹配XM
elif ss[:2] == ''+cur[0]+cur[1]: return 4,2 # 匹配XL
elif ss[0] == cur[0]: # 匹配X*
count =0
while count<len(ss) and ss[count]==cur[0]: count+=1
return count, count
elif ss[0] == cur[1]: # 匹配V/VX*
count =0
while count+1<len(ss) and ss[1+count]==cur[0]: count+=1
return 5+count, 1+count
return 0,0
看到一个超简洁代码:
class Solution:
def romanToInt(self, s: str) -> int:
d = {'I':1, 'IV':3, 'V':5, 'IX':8, 'X':10, 'XL':30, 'L':50, 'XC':80, 'C':100, 'CD':300, 'D':500, 'CM':800, 'M':1000}
return sum(d.get(s[max(i-1, 0):i+1], d[n]) for i, n in enumerate(s))
14最长公共前缀
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if len(strs) == 0: return ""
# 排序
sorteds = sorted(strs)
# 对比第一个和最后一个
end =0
while end < len(sorteds[0]) and end < len(sorteds[-1]):
if sorteds[0][end] != sorteds[-1][end]: break
end +=1
return sorteds[0][:end]
15三数之和
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
res = []
oldnum=10**5+1 # 设定一个超出范围的值
nums = sorted(nums)
while len(nums)>=3:
if sum(nums[:3]) > 0: break # 最小的三个数之和都>0,放弃吧
elif nums[0]==oldnum: # 重复值不遍历
nums = nums[1:]
continue
s,e=1,len(nums)-1 # 双指针
while s<e:
if nums[0]+nums[s]+nums[e]==0:
if [nums[0],nums[s],nums[e]] not in res: # 去除重复值
res.append([nums[0],nums[s],nums[e]])
s,e=s+1,e-1 # 改成while语句避免重复,没有任何优化效果(奇怪)
elif nums[0]+nums[s]+nums[e]>0: e-=1
else: s+=1
oldnum = nums[0] # 这句话可以提高1000ms
nums = nums[1:]
return res
16最接近的三数之和
思路同15
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
nums = sorted(nums)
res = sum(nums[:3])
while len(nums)>2:
s,e = 1, len(nums)-1
while s<e:
summ = nums[0]+nums[s]+nums[e]
if abs(summ-target) < abs(res-target): res = summ
if summ == target: return target
elif summ > target: e-=1
else: s+=1
nums = nums[1:]
if res > target and sum(nums[:3]) > target: break #最小的三个数之和都比目标大,停止吧
return res
17电话号码的字母组合
class Solution:
def letterCombinations(self, digits: str) -> List[str]:
if len(digits) == 0: return []
self.res =[]
self.backtrack('', digits)
return self.res
def backtrack(self, s:str, digits: str):
if len(digits) == 0: self.res.append(s)
else:
dic = {"2":"abc","3":"def",'4':"ghi",'5':"jkl",'6':"mno",'7':"pqrs",'8':"tuv",'9':"wxyz"}
for l in dic[digits[0]]:
self.backtrack(s+l, digits[1:])
18四数之和
19删除链表的倒数第N个结点
20有效的括号
class Solution:
def isValid(self, s: str) -> bool:
dic = {'(':')', '{':'}', '[':']'}
q = []
for ss in s:
if ss in dic.keys(): q.append(ss)
if ss in dic.values():
if len(q)>0 and ss == dic[q[-1]]: q = q[:-1] # 错误:"]"
else: return False
if len(q)>0: return False # 错误:"["
return True