2019.08.02
1.返回和为指定值的两数的索引
- 基本思想:
哈希表
- 实现:把数组中的值作为key,索引作为value,在一此遍历的过程中,一边转map,一边查找符合要求的两个数
def twoSum(self, nums: List[int], target: int) -> List[int]:
_dict = {}
for i, m in enumerate(nums):
if _dict.get(target - m) is not None:
return [_dict.get(target - m),i]
_dict[m] = i
26.删除排序数组中的重复项
- 基本思想:
双指针
- 实现:头指针初始为0,尾指针初始为1。在一次遍历过程中,若头尾元素相同,则尾指针向后移动;若头尾元素不同,则头指针之后的位置赋值为尾元素,同时头尾指针一起向后移动一个位置。注意尾指针在移动过程中不要超出数组边界。
def removeDuplicates(self, nums):
m = len(nums)
i = 0
j = 1
while j < m:
while j < m and nums[i] == nums[j]:
j += 1
while j < m and nums[i] != nums[j]:
nums[i+1] = nums[j]
i += 1
j += 1
return i+1
2019.08.03
27.移除数组中和指定值相同的元素
- 基本思想:
双指针
- 实现1:头指针初始化为0,尾指针初始化为0。在一次遍历过程中,先尾指针向后移动找到不和指定值相同的元素,然后赋值给头元素,同时头尾指针一起向后移动一个位置。
def removeElement(self, nums: List[int], val: int) -> int:
m = len(nums)
i = 0
j = 0
while j < m:
while j < m and nums[j] == val:
j += 1
if j < m:
nums[i] = nums[j]
i += 1
j += 1
return i
- 实现2:头指针h初始为0,计数器k初始为0,h+k 代表尾指针。在一次遍历过程中,先计算连续和指定值相同的元素个数,再将尾元素赋给头元素,同时头指针向后移动一个位置。
def removeElement(self, nums: List[int], val: int) -> int:
m = len(nums)
i = 0
k = 0 #记录重复元素个数
while i+k < m:
while i+k < m and nums[i+k] == val: #一定要用while而不是if,因为val值可能是连续的
k += 1
if i+k <m:
nums[i] = nums[i+k] # i代表头指针 i+k代表尾指针
i += 1
return i
35.搜索元素插入位置
- 题目等价表达:返回第一个大于等于目标值的元素索引
- 基本思想:
二分法
- 二分法模板讲解
#查找第一个大于等于目标值的元素位置:二分查找 80ms
def searchInsert(self, nums: List[int], target: int) -> int:
h = 0
t = len(nums) - 1
#考虑特殊情况,目标值不在
if target > nums[t]:
return t + 1
#位置的考虑范围[h,t]
while h < t: #退出循环时,h=t
mid = h + (t-h)//2 #注意整除的符号,注意中位数的表达
if nums[mid] < target:
h = mid + 1 #先考虑最确定的划分,元素值小于目标值时 mid 一定不符合,所以范围变为[mid+1,t]
elif nums[mid] >= target:
t = mid #再考虑不确定的划分,元素值大于等于目标值时 mid 可能符合也可能不符合,所以范围变为[h,mid]
return h
2019.08.04
88.第二个有序数组合并到第一个有序数组
- 基本思想:
双指针
- 实现:指针 i 指向第一个数组最后一个元素,指针 j 指向第二个数组最后一个元素,指针 t 指向第一个数组 i + j + 1 的位置(即合并后数组的最后一个元素位置)。i 指向元素和 j 指向元素比较大小,大的放到 t 指向位置,同时 t 指针和大元素指针向前移动。直到 i 或者 j 有一方减为 -1 时(防止数组溢出),退出循环。若是 j != -1(即第二个数组没有全部合并到第一个数组中),应该循环将第二个数组剩余部分赋值给第一个数组,无需判断 i ,因为是将第二个数组合并到第一个数组中,只要第二个数组元素合并进去就完事了。
class Solution(object):
def merge(self, nums1, m, nums2, n):
i = m - 1
j = n - 1
t = n + m -1
while i >= 0 and j >= 0:
if nums1[i] > nums2[j]:
nums1[t] = nums1[i]
i -= 1
else:
nums1[t] = nums2[j]
j -= 1
t -= 1
while j >= 0:
nums1[t] = nums2[j]
t -= 1
j -= 1
167.返回和为指定值的两数索引Ⅱ–输入有序数组
- 基本思想:
双指针
- 实现:由于是有序数组,所以从两端同时开始遍历即可,若前面元素与后面元素之和等于目标值,直接返回索引;若和大于目标值,则后面索引-1;若和小于目标值,则前面索引+1.
def twoSum(self, numbers: List[int], target: int) -> List[int]:
i = 0
j = len(numbers) - 1
while i < j:
t = numbers[i] + numbers[j]
if t == target:
return[i+1, j+1] #直接返回,而不需要append到一个list
elif t > target:
j -= 1
else:
i += 1
return [-1,-1]
217.存在重复元素
集合法
:判断数组长度和数据集合长度是否相等
return len(set(nums)) != len(nums)
哈希表
:将元素值作为key,通过hash表查询是否已存在
def containsDuplicate(self, nums: List[int]) -> bool:
_dict = {}
for k,v in enumerate(nums):
if _dict.get(v) is not None:
return True
_dict[v] = k
return False
排序法
:排序之后相邻元素必相等
nums.sort()
for i in range(len(nums)-1):
if nums[i+1] == nums[i]:
return True
return False
219.存在重复元素Ⅱ–判断重复元素索引之差是否小于k
- 基本思想:
哈希表
def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
_dict = dict()
for i,v in enumerate(nums):
if v in _dict and i - _dict[v] <= k:
return True
_dict[v] = i
return False