最长公共前缀
链接:题目链接
题目描述
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入: [“flower”,“flow”,“flight”]
输出: “fl”
示例 2:
输入: [“dog”,“racecar”,“car”]
输出: “”
解释: 输入不存在公共前缀。
解题思路 — 纵向扫描,同一列每一行
一开始想着可以直接用zip啊,纵向扫描思想确实是这样的,但是你要多少个变量来接受zip呢,这里就不好下手
所以我们想到用any函数,any的参数是一个Iterable可迭代的对象
字符串为空的进行特判即可,否则,我们遍历第一个字符串,用any来对其他行的字符串的那一列进行对比,还有要注意这里有短板效应
代码实现
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
# 纵向扫描
if not strs:
return ""
length, count= len(strs[0]),len(strs)
res_list = ["" for _ in range(length)]
for i in range(length):
c = strs[0][i]
# 下面这行代码表示有可能有其他行的字符串很短
# any的用法要注意,里面有个Iterable对象
if any(i==len(strs[j]) or strs[j][i] != c for j in range(1,count)):
return strs[0][:i]
return strs[0]
三数之和
链接:题目链接
题目描述
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
解题思路—双指针
暴力解法需要三重循环,复杂度为N^3,所以我们采用将数组先排序,固定一个数字为最小的那个数字的下标k, i,j表示k+1,len(nums)-1
当遇到重复的数字的时候,需要将i += 1,或者j -= 1,因为是往中间扫的。相应的4数之和就是将两个数字固定,再用双指针
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
res,k = [],0
for k in range(len(nums)-2):
# 这种情况肯定无法得到和为0的,因为是排序好的
if nums[k] > 0:break
# 重复的k需要跳过,因为之前的相同的值的结果集肯定已经加到res里面了
if k>0 and nums[k] == nums[k-1]:continue
i,j = k+1,len(nums)-1
while i<j:
s = nums[k]+nums[i]+nums[j]
# 和小于0的话说明太小了,将i右移即可
if s<0:
i += 1
while i<j and nums[i] == nums[i-1]: i += 1
# 和大于0的话说明太大了,将j左移即可
elif s>0:
j -= 1
# 碰到重复不进行考虑,因为在前一个k的时候肯定已经考虑过了
while i<j and nums[j] == nums[j+1]: j -= 1
else:
res.append([nums[k],nums[i],nums[j]])
i += 1
j -= 1
while i<j and nums[i] == nums[i-1]: i += 1
while i<j and nums[j] == nums[j+1]: j -= 1
return res
最接近的三数之和
链接:题目链接
题目描述
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
示例:
输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
解题思路—双指针
其实和三数之和的解题思路很像,也是用双指针的思想
但是,这里的我们每次求得一个sum都需要跟新一下最接近于target的结果
target不是0了,而是任意数,我们依旧可以用三数之和的代码,只需要稍微改动一下
代码实现
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
nums.sort()
res,k = [],0
best = 99999
def update(s):
nonlocal best
if abs(target-s) < abs(target-best):
best = s
for k in range(len(nums)-2):
# if nums[k] > 0:break
# 跳过k
if k>0 and nums[k] == nums[k-1]:continue
i,j = k+1,len(nums)-1
while i<j:
s = nums[k]+nums[i]+nums[j]
# 每次获得一个sum就需要更新best的值
update(s)
# 这里是需要和target进行比较,小就将i右移
if s<target:
i += 1
while i<j and nums[i] == nums[i-1]: i += 1
# 大就将j左移
elif s>target:
j -= 1
# 重复的剔除,相当于小优化,时间复杂度没有降低数量级
while i<j and nums[j] == nums[j+1]: j -= 1
else:
res.append([nums[k],nums[i],nums[j]])
# 和target相等的话不需要继续进行下去了,直接return即可
return s
i += 1
j -= 1
while i<j and nums[i] == nums[i-1]: i += 1
while i<j and nums[j] == nums[j+1]: j -= 1
return best