1. 数组理论基础
-
数组是存放在连续内存空间上的相同类型数据的集合。
-
数组的元素不能删除,只能覆盖。
2. 二分查找704
视频讲解:《代码随想录》算法视频公开课 (opens new window):手把手带你撕出正确的二分法 (opens new window)
状态:想到了双指针
【要素察觉】二分法的使用条件
- 有序数组
- 数组中无重复元素
【重点】区间的定义
- 二分法主要有两种定义方法:左闭右闭即[left, right],或者左闭右开即[left, right)。
- 区间的定义就是不变量,那么在循环中坚持根据查找区间的定义来做边界处理,就是循环不变量规则。
- 两种的主要区别是while条件和middle的赋值对应变化。
【代码实现】
(双指针)while+左闭右闭
class Solution:
def search(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums) - 1
if nums is None or len(nums) == 0:
return -1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] > target:
right = mid - 1
elif nums[mid] < target:
left = mid + 1
return -1
(双指针)while+左闭右开
下一个查询区间不会去比较nums[mid]。
class Solution:
def search(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums) - 1
if nums is None or len(nums) == 0:
return -1
while left < right: # 区别点1
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] > target:
right = mid # 区别点2
elif nums[mid] < target:
left = mid + 1
return -1
(暴力)迭代法
class Solution:
def search(self, nums: List[int], target: int) -> int:
for i in range(len(nums)):
if nums[i] == target:
return i
return -1
【练习题】
- 35.搜索插入位置(opens new window)
- 34.在排序数组中查找元素的第一个和最后一个位置(opens new window)
- 69.x 的平方根(opens new window)
- 367.有效的完全平方数(opens new window)
3. 移除元素27
视频讲解:《代码随想录》算法视频公开课 (opens new window):数组中移除元素并不容易!LeetCode:27. 移除元素 (opens new window)
状态:用的暴力法
【思路】只能覆盖
要知道数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。
思路一:暴力解法
思路二:快慢指针
【代码实现】
(暴力解法)while + for循环,交换位置
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
i, n = 0, len(nums)
while i < n:
if nums[i] == val:
for j in range(i, n - 1):
nums[j] = nums[j + 1]
n -= 1
else:
i += 1
return n
(暴力解法)while+while交换位置后pop
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
i = 0
while i < len(nums):
while i < len(nums) and nums[i] == val:
nums[i] = nums[-1]
nums.pop()
i += 1
return len(nums)
(双指针)快慢指针
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
# 双指针,左指针慢
left, right = 0,0
while right < len(nums):
if nums[right] == val:
# 等于就跳过
right += 1
else:
# 不等就存储
nums[left] = nums[right]
left += 1
right += 1
return left
(双指针) 左右指针
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
left = 0
right = len(nums) - 1
while left <= right:
if nums[left] == val:
nums[left] = nums[right]
right -= 1
else:
left += 1
return left