剑指Offer典型题整理 - 争取做最好的题解
整理时间:2020年02月21日
1 题目描述
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。
示例
输入:nums = [2,7,11,15], target = 9
输出:[2,7] 或者 [7,2]
输入:nums = [10,26,30,31,47,60], target = 40
输出:[10,30] 或者 [30,10]
限制:
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^6
2 题解
这道题不难,就是一个典型的对撞指针问题,定义左指针left和右指针right,两个指针从数组左右两端往中间移动,直至相遇则退出,python代码如下:
python代码
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if len(nums) == 1: return []
left, right = 0, len(nums) - 1
while left < right:
cur_sum = nums[left] + nums[right]
if cur_sum == target:
return [nums[left], nums[right]]
elif cur_sum > target:
right -= 1
else:
left += 1
return []
3 扩展
这道题限定了数组nums是递增有序的,如果nums是无序的,这个题就变成了LeetCode第1题:两数之和。这里顺便整理一下这道经典的题目。
3.1 题目描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
3.2 示例
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
3.3 题解
3.3.1 暴力解
这道题最容易想到的就是暴力解法,两层for循环解决战斗,但是太丑陋复杂度太高,我们忽略。
3.3.2 排序后转化为上面的题目
复杂度 O ( n l o g n ) O(nlogn) O(nlogn),勉强说的过去,但是还是不够好,而且排序之后原来的索引顺序就变了。
3.3.3 利用哈希
假如a+b=target,则b=target-a,另外由于我们需要返回下标,因此最好的方法是使用dict
记录数字及其对应下标,下面的写法优美且高效,时间复杂度
O
(
n
)
O(n)
O(n):
python代码
def towSum(nums, target):
d = {}
for index, num in enumerate(nums):
if target - num in d:
return [d[target-num], index]
d[num] = index
return []
(完)