链接可直接跳转
哈希
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]
提示:
2 <= nums.length <= 104-109 <= nums[i] <= 109-109 <= target <= 109- 只会存在一个有效答案
python
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
for i in range(len(nums)):
for n in range(i+1,len(nums)):
if target==nums[i]+nums[n]:
return [i,n]
这是最简单的做法,即直接遍历整个列表,从第一个值开始遍历,如果从当前位置到最后位置中有和当前位置值相加为目标值的即返回这两个位置。
49. 字母异位词分组(中等)
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
示例 1:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出:[["bat"],["nat","tan"],["ate","eat","tea"]]
解释:
- 在 strs 中没有字符串可以通过重新排列来形成
"bat"。 - 字符串
"nat"和"tan"是字母异位词,因为它们可以重新排列以形成彼此。 - 字符串
"ate","eat"和"tea"是字母异位词,因为它们可以重新排列以形成彼此。
示例 2:
输入: strs = [""]
输出:[[""]]
示例 3:
输入: strs = ["a"]
输出:[["a"]]
提示:
1 <= strs.length <= 1040 <= strs[i].length <= 100strs[i]仅包含小写字母
python
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
d=defaultdict(list)
for s in strs:
sorted_s=''.join(sorted(s))
d[sorted_s].append(s)
return list(d.values())
这个稍微难一些,并且会用到新东西。下面一行一行拆解:
d=defaultdict(list) 这个是当你访问一个不存在的键时,它不会报错,而是会自动创建这个键,并把它的值设为一个空列表 []。这样我们就不用写if语句判断键是否存在了。
然后开始遍历列表中的每个字符串。
sorted_s = ''.join(sorted(s)) 对于每个字符串 s,例如第一个字符串 "eat":
sorted(s)会将字符串拆成字符并排序,得到 ['a', 'e', 't']。
''.join(...)再将这个字符列表拼接回一个字符串 "aet"。这个 "aet"就是这组字母异位词的唯一标识(钥匙) 。无论原字符串是 "eat"、"tea"还是 "ate",它们排序后都会得到相同的 "aet"。
分组归位 (d[sorted_s].append(s))
这是最精妙的一步。我们通过上一步生成的密钥 sorted_s来操作字典 d。
如果是第一次遇到 "aet"这个键,d会自动创建 "aet"键,并将其值初始化为空列表 [],然后立刻将原字符串 "eat"添加进去。
当处理到 "tea"时,排序后密钥同样是 "aet"。此时 d["aet"]这个键已经存在,其值是 ["eat"],我们直接调用 append("tea"),列表就变成了 ["eat", "tea"]。
处理完所有字符串后,字典 d的内容类似这样:{"aet": ["eat", "tea"], "ant": ["tan"]}。
输出结果 (return list(d.values()))
最后,我们不需要关心键是什么,只需要所有的分组结果。d.values()返回的就是字典中所有值的视图,即 [["eat", "tea"], ["tan"]]。用 list()将其转换为列表并返回,就得到了最终答案 。
128. 最长连续序列(中等)
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n)的算法解决此问题。
示例 1:
输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
示例 2:
输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9
示例 3:
输入:nums = [1,0,1,2]
输出:3
提示:
0 <= nums.length <= 105-109 <= nums[i] <= 109
python
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
st=set(nums)
ans=0
for x in st:
if x-1 in st:
continue
y=x+1
while y in st:
y+=1
ans=max(ans,y-x)
return ans
一看到这个题第一反应是排序,但是题目说时间复杂度为O(n),但是排序为O(nlogn),所以考虑哈希表。
首先把nums转为哈希集合,这样判断数字在nums里只需要O(1)。然后遍历哈希集合,如果x-1在集合里,那么x可以直接跳过,因为不可能比从x-1更长了。最后设置y为x+1,如果y在集合里,则y再加一,最后ans为现有最大ans和当前y-x中的最大值。
比如
输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
这个就是x=1,y=2,3,4 然后最后一次4也在集合中y会再加一,这个时候y=5,所以5-1=4。
双指针
283. 移动零(简单)
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
提示:
1 <= nums.length <= 104-231 <= nums[i] <= 231 - 1
python
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
left=right=0
n=len(nums)
while right<n:
if nums[right]!=0:
nums[left],nums[right]=nums[right],nums[left]
left+=1
right+=1
这一题很巧妙的点在于用双指针可以互换数组里面数字的位置,可以自己画一下图理解一下。
