11. 盛最多水的容器
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
【思路】
显而易见,这道题可以求得面积公式:
max
(
(
j
−
i
)
∗
min
(
h
e
i
g
h
t
[
i
]
,
h
e
i
g
h
t
[
j
]
)
)
\max( (j - i ) * \min( height[i], height[j]) )
max((j−i)∗min(height[i],height[j]))
更显而易见无脑双循环暴力求解会导致超时,因此此题需要使用双指针动态规划求解。
【实现】
class Solution:
def maxArea(self, height: List[int]) -> int:
i, j, res = 0, len(height) - 1, 0
while i < j:
w = j - i
bool1 = 1 * (height[i] < height[j])
bool2 = 1 - bool1
tmp = w * (bool1 * (height[i]) + bool2 * (height[j]))
i += bool1
j -= bool2
res = max(res, tmp)
return res
14. 最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入:strs = [“flower”,“flow”,“flight”]
输出:“fl”
【思路】
这道题是第二次做了,打开刷题界面看到自己8个月前写的代码真是复杂到吃惊。思路还是比较简单的暴力循环,在实现方面精简了些。
【实现】
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if len(strs)==0: return ''
pre = ''
for i in range(1, len(strs[0]) + 1):
if len(set([s[:i] for s in strs])) == 1:
pre = strs[0][:i]
continue
break
return pre
15. 三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
【思路】
这道题也是二刷了,并且之前找实习面试的时候也问到了,按照极大似然思想,这也算是高频题了。最简单的方法就是三重循环,不过必然超时。优化方案是将数列排序,固定一个点,另外两个点使用指针对撞法。
注意:题目要求返回不重复的三元组,故要进行一定优化。
【实现】
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
res=[]
for i in range(len(nums)-2):
if nums[i]>0: break
if i>0 and nums[i]==nums[i-1]: continue
l,r=i+1,len(nums)-1
while l<r:
s=nums[i]+nums[l]+nums[r]
if s==0:
res.append([nums[i],nums[l],nums[r]])
l+=1
r-=1
while l<r and nums[r]==nums[r+1]:
r-=1
while l<r and nums[l]==nums[l-1]:
l+=1
if s>0:r-=1
if s<0:l+=1
return res