给你 n n n 个非负整数 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1,a2,...,an,每个数代表坐标中的一个点 ( i , a i ) (i, a_i) (i,ai) 。在坐标内画 n n n
条垂直线,垂直线 i i i 的两个端点分别为 ( i , a i ) (i, a_i) (i,ai) 和 ( i , 0 ) (i, 0) (i,0) 。找出其中的两条线,使得它们与 x x x
轴共同构成的容器可以容纳最多的水。
- n = h e i g h t . l e n g t h n = height.length n=height.length
- 2 < = n < = 3 ∗ 1 0 4 2 <= n <= 3 * 10^4 2<=n<=3∗104
- 0 < = h e i g h t [ i ] < = 3 ∗ 1 0 4 0 <= height[i] <= 3 * 10^4 0<=height[i]<=3∗104
采用双指针法从两端向中间移动,left为左边指针,从左向右移动,right为右边指针,从右向左移动。
选择移动后可以得到相对更长边长或边长有增长一端优先移动(好啰嗦,看了题解发现可以归纳为一句话,,,移动较短边),并记录过程中获得的最大容量
class Solution:
def maxArea(self, height: List[int]) -> int:
left = 0
right = len(height)-1
area_max = 0
while left != right:
area = min(height[left], height[right]) * (right- left)
area_max = max(area, area_max)
if height[left] < height[right]:
left += 1
else:
right -= 1
return area_max
好像都是用双指针法,没啥更优的解法了似乎?(如果有,请告诉我)
编写一个函数来查找字符串数组中的最长公共前缀。
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if not strs:
return ""
prefix, count = strs[0], len(strs)
for i in range(1, count):
prefix = self.lcp(prefix, strs[i])
if not prefix:
break
return prefix
def lcp(self, str1, str2):
length, index = min(len(str1), len(str2)), 0
while index < length and str1[index] == str2[index]:
index += 1
return str1[:index]
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/longest-common-prefix/solution/zui-chang-gong-gong-qian-zhui-by-leetcode-solution/
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if not strs:
return ""
length, count = len(strs[0]), len(strs)
for i in range(length):
c = strs[0][i]
if any(i == len(strs[j]) or strs[j][i] != c for j in range(1, count)):
return strs[0][:i]
return strs[0]
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/longest-common-prefix/solution/zui-chang-gong-gong-qian-zhui-by-leetcode-solution/
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
def lcp(start, end):
if start == end:
return strs[start]
mid = (start + end) // 2
lcpLeft, lcpRight = lcp(start, mid), lcp(mid + 1, end)
minLength = min(len(lcpLeft), len(lcpRight))
for i in range(minLength):
if lcpLeft[i] != lcpRight[i]:
return lcpLeft[:i]
return lcpLeft[:minLength]
return "" if not strs else lcp(0, len(strs) - 1)
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/longest-common-prefix/solution/zui-chang-gong-gong-qian-zhui-by-leetcode-solution/
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
def isCommonPrefix(length):
str0, count = strs[0][:length], len(strs)
return all(strs[i][:length] == str0 for i in range(1, count))
if not strs:
return ""
minLength = min(len(s) for s in strs)
low, high = 0, minLength
while low < high:
mid = (high - low + 1) // 2 + low
if isCommonPrefix(mid):
low = mid
else:
high = mid - 1
return strs[0][:low]
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/longest-common-prefix/solution/zui-chang-gong-gong-qian-zhui-by-leetcode-solution/
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if not strs:
return ""
str0 = min(strs)
str1 = max(strs)
for i in range(len(str0)):
if str0[i] != str1[i]:
return str0[:i]
return str0
class Solution(object):
def longestCommonPrefix(self, strs):
ans = ''
for i in zip(*strs):
if len(set(i)) == 1:
ans += i[0]
else:
break
return ans
作者:javaniuniu
链接:https://leetcode-cn.com/problems/longest-common-prefix/solution/shi-yong-zip-ji-xing-dai-ma-jian-dan-gao-ding-pyth/
横向扫描
纵向扫描
分治
时间复杂度: O ( m n ) O(mn) O(mn),其中 m m m 是字符串数组中的字符串的平均长度, n n n 是字符串的数量。时间-复杂度的递推式是 T ( n ) = 2 ⋅ T ( 2 n ) + O ( m ) T(n)=2⋅T( 2n )+O(m) T(n)=2⋅T(2n)+O(m),通过计算可得 T ( n ) = O ( m n ) T(n)=O(mn) T(n)=O(mn)。
空间复杂度: O ( m l o g n ) O(m\ logn) O(m logn),其中 m m m 是字符串数组中的字符串的平均长度, n n n 是字符串的数量。空间复杂度主要取决于递归调用的层数,层数最大为 l o g n logn logn,每层需要 m m m 的空间存储返回结果。
二分查找
给你一个包含 n n n 个整数的数组 n u m s nums nums,判断 n u m s nums nums 中是否存在三个元素 a , b , c a,b,c a,b,c ,使得 a + b + c = 0 ? a + b + c = 0 ? a+b+c=0? 请你找出所有和为 0 0 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
nums.sort()
ans = list()
# 枚举 a
for first in range(n):
# 需要和上一次枚举的数不相同
if first > 0 and nums[first] == nums[first - 1]:
continue
# c 对应的指针初始指向数组的最右端
third = n - 1
target = -nums[first]
# 枚举 b
for second in range(first + 1, n):
# 需要和上一次枚举的数不相同
if second > first + 1 and nums[second] == nums[second - 1]:
continue
# 需要保证 b 的指针在 c 的指针的左侧
while second < third and nums[second] + nums[third] > target:
third -= 1
# 如果指针重合,随着 b 后续的增加
# 就不会有满足 a+b+c=0 并且 b
if second == third:
break
if nums[second] + nums[third] == target:
ans.append([nums[first], nums[second], nums[third]])
return ans
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/3sum/solution/san-shu-zhi-he-by-leetcode-solution/
时间复杂度: O ( N 2 ) O(N^2) O(N2),其中 N N N 是数组 n u m s nums nums 的长度。
空间复杂度: O ( l o g N ) O(log\ N) O(log N)。我们忽略存储答案的空间,额外的排序的空间复杂度为 O ( l o g N ) O(log\ N) O(log N)。然而我们修改了输入的数组 n u m s nums nums,在实际情况下不一定允许,因此也可以看成使用了一个额外的数组存储了 n u m s nums nums 的副本并进行排序,空间复杂度为 O ( N ) O(N) O(N)。