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 = 0j = 1while j < m:while j < m and nums[i] == nums[j]:j += 1while j < m and nums[i] != nums[j]:nums[i+1] = nums[j]i += 1j += 1return i+1
2019.08.03
27.移除数组中和指定值相同的元素
- 基本思想:
双指针
- 实现1:头指针初始化为0,尾指针初始化为0。在一次遍历过程中,先尾指针向后移动找到不和指定值相同的元素,然后赋值给头元素,同时头尾指针一起向后移动一个位置。
def removeElement(self, nums: List[int], val: int) -> int:m = len(nums)i = 0j = 0while j < m:while j < m and nums[j] == val:j += 1if j < m:nums[i] = nums[j]i += 1j += 1return i
- 实现2:头指针h初始为0,计数器k初始为0,h+k 代表尾指针。在一次遍历过程中,先计算连续和指定值相同的元素个数,再将尾元素赋给头元素,同时头指针向后移动一个位置。
def removeElement(self, nums: List[int], val: int) -> int:m = len(nums)i = 0k = 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 += 1return i
35.搜索元素插入位置
- 题目等价表达:返回第一个大于等于目标值的元素索引
- 基本思想:
二分法
- 二分法模板讲解
#查找第一个大于等于目标值的元素位置:二分查找 80ms def searchInsert(self, nums: List[int], target: int) -> int:h = 0t = len(nums) - 1 #考虑特殊情况,目标值不在if target > nums[t]:return t + 1#位置的考虑范围[h,t]while h < t: #退出循环时,h=tmid = 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 - 1j = n - 1t = n + m -1while i >= 0 and j >= 0:if nums1[i] > nums2[j]:nums1[t] = nums1[i]i -= 1else:nums1[t] = nums2[j]j -= 1t -= 1while j >= 0:nums1[t] = nums2[j]t -= 1j -= 1
167.返回和为指定值的两数索引Ⅱ–输入有序数组
- 基本思想:
双指针
- 实现:由于是有序数组,所以从两端同时开始遍历即可,若前面元素与后面元素之和等于目标值,直接返回索引;若和大于目标值,则后面索引-1;若和小于目标值,则前面索引+1.
def twoSum(self, numbers: List[int], target: int) -> List[int]:i = 0j = len(numbers) - 1while i < j:t = numbers[i] + numbers[j]if t == target:return[i+1, j+1] #直接返回,而不需要append到一个listelif t > target:j -= 1else:i += 1return [-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] = kreturn False
排序法
:排序之后相邻元素必相等
nums.sort()for i in range(len(nums)-1):if nums[i+1] == nums[i]:return Truereturn 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] = ireturn False