例题:
1.两数之和
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
思路:先确定第一个数字,第二个数字从第一个数字后面依次取得,得到两个数字之和与目标数字比较,直到相等才输出两个数字的下标。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
lens = len(nums)
for i in range(0,lens):
for j in range(i+1,lens):
if nums[i] + nums[j] == target:
return [i,j]
2.最接近的三数之和
给你一个长度为 n
的整数数组 nums
和 一个目标值 target
。请你从 nums
中选出三个整数,使它们的和与 target
最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。
思路:先用二分法确定一个初值,之后对数组排序,利用双指针首先遍历得到索引 c,然后计算 c,左指针 i,右指针 j 对应数字之和,如果大于 target,j 向内移动,否则 i 向内移动。
注:1)float('inf') = 正无穷
2)排序,遍历,双指针
3)i 的初始值不是 c + 1,是为了减少计算量,用二分法得到一个合理的初始值
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
nums, r, end = sorted(nums), float('inf'), len(nums) - 1
for c in range(len(nums) - 2):
i, j = max(c + 1, bisect.bisect_left(nums, target - nums[end] - nums[c], c + 1,end) - 1), end
while r != target and i < j:
s = nums[c] + nums[i] + nums[j]
r, i, j = min(r, s, key=lambda x: abs(x - target)), i + (s < target), j - (s > target)
return r
任务:
1.移除元素
给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1)
额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
思路:遍历数组,数组中元素与指定元素一致时,利用remove直接删除。
remove:删除最近一个元素。
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
for i in nums[:]:
if i == val:
nums.remove(i)
return len(nums);nums
给你一个有序数组 nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
思路:如果采用nums[i]+nums[i+1]经常会出现下标溢出的情况。先设置一个计数变量,使得相同数值放在一个下标中。
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
lens = len(nums)
index = 0
for i in range(1,lens):
if nums[index] == nums[i]:
continue
nums[index+1] = nums[i]
index += 1
return len(nums)
3.三数之和
给你一个包含 n
个整数的数组 nums
,判断 nums
中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0
且不重复的三元组。
注意:答案中不可以包含重复的三元组。
算法流程:
1)特判,对于数组长度 n,如果数组为 null 或者数组长度小于 3,返回 []。
2)对数组进行排序。
3)遍历排序后数组:
若 nums[i]>0:因为已经排序好,所以后面不可能有三个数加和等于 0,直接返回结果。
对于重复元素:跳过,避免出现重复解
令左指针 L=i+1,右指针 R=n-1,当 L<R时,执行循环:
当 nums[i]+nums[L]+nums[R]==0,执行循环,判断左界和右界是否和下一位置重复,去除重复解。并同时将 L,R 移到下一位置,寻找新的解
若和大于 0,说明 nums[R]太大,R左移
若和小于 0,说明 nums[L]太小,L 右移
作者:wu_yan_zu(原文链接)
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
n=len(nums)
if(not nums or n<3):
return []
nums.sort()
res=[]
for i in range(n):
if(nums[i]>0):
return res
#去掉重复数据
if(i>0 and nums[i]==nums[i-1]):
continue
#设置双指针
L=i+1
R=n-1
while(L<R):
if(nums[i]+nums[L]+nums[R]==0):
res.append([nums[i],nums[L],nums[R]])
while(L<R and nums[L]==nums[L+1]):
L=L+1
while(L<R and nums[R]==nums[R-1]):
R=R-1
L=L+1
R=R-1
elif(nums[i]+nums[L]+nums[R]>0):
R=R-1
else:
L=L+1
return res