1. 两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]
- 首先应明确题目中的数组是否有序,如题目不明确说明,我们一般认为他无序,而无序的情况下除了使用暴力解法,我们考虑使用哈希表,时空复杂度都为O(N)
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
dic = {}
for i, num in enumerate(nums):
if target - num in dic:
return [dic[target - num], i]
dic[num] = i
return []
- 但是如果题目说明给定一个有序的数组呢?是否有其他优化的方案?答案是肯定的!有序的情况下使用双指针,时间复杂度O(N),空间复杂度O(1)
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
left, right = 0, len(nums) - 1
while left < right:
sum = nums[left] + nums[right]
if sum == target:
return [left, right]
elif sum > target:
right -= 1
else:
left += 1
return []
771. 宝石与石头
给你一个字符串 jewels 代表石头中宝石的类型,另有一个字符串 stones 代表你拥有的石头。 stones 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石。
字母区分大小写,因此 "a" 和 "A" 是不同类型的石头。
示例 1:
输入:jewels = "aA", stones = "aAAbbbb"
输出:3
示例 2:
输入:jewels = "z", stones = "ZZ"
输出:0
- 最简单的想法就是利用二重循环来解决,但是这会使时间复杂度达到O(N^2),这是我们极不想看到的。我们考虑用哈希表来解决,在 Python 中有两类重要的哈希结构,利用哈希结构,我们能使判断元素是否在容器中这样的 in 操作的时间复杂度从O(N)降低到O(1),第一类哈希结构是 set,下面的算法时间复杂度为O(M+N),空间复杂度为O(M)
class Solution:
def numJewelsInStones(self, jewels: str, stones: str) -> int:
jewelsSet = set(jewels)
return sum(s in jewelsSet for s in stones)
- 第二类哈希结构是 dict,而 Counter 容器是一种高级的 dict,他可以记录每个元素出现的次数,下面的算法时间复杂度为O(M+N),空间复杂度为O(len(set(stones))
class Solution:
def numJewelsInStones(self, jewels: str, stones: str) -> int:
counter = Counter(stones)
return sum(counter[i] for i in jewels)