力扣学习笔记 day3

今日题号:11,14,15

题 011.盛水最多的容器

题意

给定一个数组,从中取出两个数,视作盛水容器的两边,将两数之间的距离视作容器的底部,求能使容器容积最大的两个数。

eg.

输入: [1,8,6,2,5,4,8,3,7]
输出: 49
解释: 图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。


解题思路

本题求得实际上就是 min(左高度,右高度)*左右间距 的最大值

如同许多优秀题解的方法,双指针是一种理解较为容易且容易实施的方案,具体实施方法如下:

  • 考虑到题目实际上就是求一个矩形的面积,所以首先令一边达到最长。即从数组的左右两端往中间移动,不断更新容积的最大值
  • 每次判断左右两边那个更小,如同水桶定律,水桶装多少取决于它最短的那根板,所以找到二者中更小的那个数,比较当前容积和目前最大值
  • 比较后,从数值更小的一侧向内推进
  • 两点相遇后,循环结束

代码

def maxArea(self,height:List[int])->int:
	left,right=0,len(height)-1
	res=0
	
	while left<right:
		if height[left]<height[right]:
			res=max(res,height[left]*(right-left))
			left+=1
		else:
			res=max(res,height[right]*(right-left))
			right-=1
	return res

题 014.最长公共前缀

题意

从一个字符串数组中找到最长公共前缀,若不存在返回空字符串。


解题

本题比较简单,因为求的是整个数组中的所有字符串的公共前缀,所以只要比较字典序最大和最小的两个。
利用max和min函数找到数组中字典序最大和最小值,找到这两个字符串的最长公共前缀即可。

关键代码

#字典序最小x,最大y
for i in range(len(x)):
	if x[i]!=y[i]:
		return x[:i]
return x

题 015.三数之和

题意

对于一个由整数构成的数组,求其中是否存在三个数,它们的和为0,若存在,返回所有这样的组合。(不可以重复)

eg.

输入: nums = [-1,0,1,2,-1,-4]
输出: [[-1,-1,2],[-1,0,1]]


解题思路

参考部分题解,双指针方法效率较高。

具体做法是:

  • 先将数组进行排序
  • 针对第一个数进行循环
  • 每循环到一个数
    • 对于后两个数分别作为指针,从剩余数组的两端向内压缩,进行查找
    • 当三个数的和为零时,将答案储存
    • 针对后两个数(即两个指针),继续向内压缩,并确保不会重复
  • 第一个数使用完后,确保下一个数与它不同,不然会出现重复的情况,具体的做法是
if k>0 and nums[k]==nums[k-1]:
	continue
  • 如果嫌以上提到的避免重复的操作麻烦,可以换种思路,将答案res暂时定义为set类型,这样遍历时不管有没有重复通通add进去,最后输出时再用list(res)转为list类型

代码

def threeSum(self, nums: List[int]) -> List[List[int]]:
	m=len(nums)
	if m<3:
		return []
	nums.sort()
	res=[]
	for k in range(m-2):#第一个数顶多遍历到第m-3位
		if nums[k]>0: break#若第一个数大于0,则不可能是答案
		if k>0 and nums[k]==nums[k-1]:#从第一个数的角度避免重复
			continue
		i,j=k+1,m-1
		while i<j:
			sum=nums[i]+nums[j]+nums[k]
			#向内压缩
			if sum>0:
				j-=1
			elif sum<0:
				i+=1
			else:
				res.append([nums[k],nums[i],nums[j]])
				#避免后两个数的重复
				while i<j and nums[i]==nums[i+1]:
					i+=1
				while i<j and nums[j]==nums[j-1]:
					j-=1
				i+=1
				j-=1
	return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值