题目详细说明请自行到题库 - 力扣 (LeetCode)搜寻题号
1. 两数和
利用数组的有序,使用两个指针,一个为l,指向数组开头,一个为r,指向数组结尾;
和大于target时右边指针左移一个,获得比当前小的下一个和;
和小于target时左边指针右移一个,获得比当前大的下一个和;
循环条件为 l < r ,循环结束时就把所有的和都遍历了一遍, 时间复杂度为O(n);
167. Two Sum II - Input array is sorted
给定一个已按照升序排列的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
class Solution:
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
if len(numbers) < 2:
return None
l = 0
r = len(numbers) - 1
while l < r:
s = numbers[l] + numbers[r]
if s == target:
#这道题下标从1开始的
return [l + 1, r + 1]
elif s < target:
l += 1
else:
r -= 1
return None
2. 扩展, 三数和
怎么把三数和转化为两数和呢?
我们可以遍历一次数组取每一个 nums[i] ,使三数和等于target相当于
在 nums[ i + 1 : ] 中找两个下标 l , r 使 nums[l] + nums[r] == target - nums[i]
这样就转化为两数和问题, 时间复杂度为 O(n²) , 注意去除重复答案
15. 3Sum
给定一个包含 n 个整数的数组nums,判断nums中是否存在三个元素 a,b,c ,使得a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
class Solution:
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
#先排序
nums.sort()
res = []
#current标记用于去重
current = '-1'
for i, value in enumerate(nums):
if current == value:
continue
current = value
l = i + 1
r = 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
#去掉重复l
while l < r and nums[l] == nums[l - 1]:
l += 1
#去掉重复r
while r > l and nums[r] == nums[r + 1]:
r -= 1
elif s < 0:
l += 1
else:
r -= 1
return res
还有一道4数和的题目, 思路是一样的, 再加一层循环, 时间复杂度为 O(n³)
3. 盛水最多容器
用双指针做,取2个指针,最左 l 和最右 r , 计算两块板装的面积
当 l 的板比 r 的高时 , r -= 1
当 r 的板比 l 的高时, l += 1
双指针遍历相当于求每个宽度下的最大面积, 从中取一个最大值, 时间复杂度为O(n)
11. Container With Most Water
给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i,ai) 。在坐标内画 n 条垂直线,垂直线 i的两个端点分别为 (i,ai) 和 (i, 0)。找出其中的两条线,使得它们与x轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且n的值至少为 2。
class Solution:
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
res = 0
l, r = 0, len(height) - 1
while l < r:
#求面积, 等于宽度乘以 l , r 中高度比较小的那个值
res = max(res, (r - l) * min(height[l],height[r]))
if height[l] > height[r]:
r -= 1
else:
l += 1
return res
4. 搜寻二维矩阵
使用两层循环搜索时间复杂度为O(n²) , 而且没用到题目给的有序的条件
我们可以假设右上角的值 matrix[x][y] 为初始值, 其中 x = 0 , y = n
当matrix[x][y] < target时, 说明 matrix[x] 这一行上的值都比 target 小, x += 1
当matrix[x][y] > target时, 说明matrix在y这一列上的值都比target 大, y -= 1
找到target时返回True, 超出矩阵后返回False 时间复杂度为 O(m + n)
240. Search a 2D Matrix II
编写一个高效的算法来搜索m x n矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:
每行的元素从左到右升序排列。
每列的元素从上到下升序排列。
class Solution:
def searchMatrix(self, matrix, target):
"""
:type matrix: List[List[int]]
:type target: int
:rtype: bool
"""
#判断矩阵有没有值
x = len(matrix)
if x == 0:
return False
y = len(matrix[0])
if y == 0:
return False
#y取最后一列的下标
y -= 1
i = 0
while i < x and y >= 0:
if matrix[i][y] < target:
i += 1
elif matrix[i][y] > target:
y -= 1
else:
return True
return False