一、二分法查找:
题目:
1.问题剖析:一组数字升序、无重复,才能用二分查找
2.解法
- 左闭右闭区间[left,right]
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left,right=0,len(nums)-1
while left<=right:
middle=left+(right-left)//2
if nums[middle]>target:
right=middle-1
elif nums[middle]<target:
left=middle+1
else:
return middle
return -1
- 左闭右开区间[left,right)
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left,right=0,len(nums)
while left<right:
middle=left+(right-left)//2
if nums[middle]>target:
right=middle
elif nums[middle]<target:
left=middle+1
else:
return middle
return -1
3.题目要点与收货:
- 确立区间开闭[L,R] or [L,R)
- 根据区间开闭确定while迭代条件(不冲突原则,若都为闭区间,可以取等于号;一开一闭,取不等号)
- 根据区间开闭确定right迭代公式(闭区间的一端,不能为原值,需要移动,nums[middle]><target已经成功判断middle不在后续查找的区间内,而while的条件是可以取等于号的)
- python的注解,变量注解(var : 类型),函数注解(->类型)
二、移除元素
题目:
1.问题剖析:数组不能删除元素,只能覆盖元素!
2.解法:
- 暴力移动:两个循环,O(n^2)
(版本二)暴力法
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
i, l = 0, len(nums)
while i < l:
if nums[i] == val: # 找到等于目标值的节点
for j in range(i+1, l): # 移除该元素,并将后面元素向前平移
nums[j - 1] = nums[j]
l -= 1
i -= 1
i += 1
return l
- 双指针法:
构建两个指针,一个fast,一个slow。fast用来遍历元素,比较是否与val相等,slow用来覆写,将不等于val的元素存储,并覆盖原来的元素。slow指向不重复元素后面一个位置(下一个不重复元素需要插入的位置),fast指针一直遍历数组。
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
fast=0
slow=0
while fast<=len(nums)-1:
if nums[fast]!=val:
nums[slow]=nums[fast]
slow+=1
fast+=1
return slow
- 双向指针法:
构建两个指针,一个left,一个right。在 while left <= right的条件下(因为都是闭区间,所以用<=),将两个指针向中间移动,当left遇到val时,将右指针元素赋值给左指针元素,两个指针再向中间移动一步,继续循环。
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
left,right=0,len(nums)-1
while left <= right:
while left<=right and nums[left]!=val:
left+=1
while left<=right and nums[right]==val:
right-=1
if left<right:
nums[left]=nums[right]
left+=1
right-=1
return left
3.题目要点与收货:
索引 i 的两个意义:
- 索引位置元素相对于0位置的 i 个偏移量
- 索引位置元素之前,已经存储了 i 个元素
常用操作:
前提条件:设置指针为0
执行阶段:
while 循环条件
1.判断条件
2.赋值操作
3.指针移动,大小+1
在跳出while循环后,指针数字的大小,就代表了循环中的操作执行总次数。在本题中,代表了在指针位置之前已经存储了i(i=指针的数字大小)个元素。所以直接返回指针即可,代表了移除target后元素的个数