- 704.左闭右开和左闭右闭已掌握,35.搜索插入位置
- 34. 在排序数组中查找元素的第一个和最后一个位置 (没看完)
- 27.移出元素 还需要多写写,有时候用for \while\if有点晕
一.数组理论基础
数组是存放在连续空间内存上的相同类型数据的集合
可以索引,连续内存上储存,所以插入和删除,需要移动其他元素。
需要注意:1.index从0开始 2.内存连续
二. 704.二分查找
力扣题目链接 704.二分查找:
个人觉得使用左闭右闭比较好想一点!强烈推荐使用,一定要注意,因为我们使用index大小传递了数值的相对大小;所以非常要注意二分法的适用范围:1.有序的 2.非重复(重复的话,index不就不确定了)
总之写代码上,要注意:1.注意边界 2.注意target和数组的值比较的 3.mid要放在while里面,要保证可变
*
想不清楚,可以举个具体的例子,比如说:
1.我现在现在[2,4,6,8]找7,刚开始left=0,right=3,mid=1,nums[1]=4<7,所以二分后,target在右边半块,所以把左边的边界赋为mid+1=2(因为num[mid]已经知道不是target,所以考虑左闭右闭,边界能够定位到mid+1);
2. 现在left=2,right=3,mid=2,nums[2]=6<7,target在二分后的右半块,left赋值为3;
3. 此时,还是满足while循环条件,接着left=right=3,mid=3,nums[mid]=8>7,target在左半块,直接right=mid-1=2,此时left=3>right=2,不满足循环条件,while退出,执行return-1
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums)-1
while left <= right:
mid = left +(right-left)//2 #因为是整数数组
if nums[mid] < target:
left = mid+1
elif nums[mid] > target:
right = mid-1
else:
return mid
return -1
在扩展一点左闭右开的代码:
修改:
1.right初值【否则会无法覆盖最右边的值】
2. while条件(左闭右开,左边不能等于右边)
3. 3.right=mid(right边界取不到,但是沿用以前mid-1,这个值事实情况会需要到,不能在代码中让她取不到)
`class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums)
while left < right:
mid = left +(right-left)//2 #因为是整数数组
if nums[mid] < target:
left = mid+1
elif nums[mid] > target:
right = mid
else:
return mid
return -1
**拓展 35.搜索插入位置,给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。**主要改动在最后的return上面,想清楚就行
我刚开始写的:力扣上也正确
力扣链接
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums)-1
while left <= right:
mid =left + (right-left)//2
if nums[mid] > target:
right = mid-1
elif nums[mid] < target:
left = mid+1
else:
return mid
return mid+1 if nums[mid] < target else mid
答案在最后一行 return right+1,等下准备问问???【return left就行】
因为在最后一次循环,left=right=mid
如果target>num[mid],left=mid+1=right+1,我想要插在mid+1位;
如果target<num[mid],right=mid-1=left-1,我想要插在mid位
拓展 34.在排序数组上查找元素的第一个位置和最后一个位置:主要改动在最后的return上面,想清楚就行
我刚开始写的:本来先用递归,分成两节子去找,没写出来
看到答案有四种解法,我震惊!一会梳理一下
三. 27.移除元素
力扣题目
难点:要知道数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。
暴力解法(注意用的while,我用for死活跑不出来,for的循环变量i是不能变动的)
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
n = len(nums)
s = 0
while s<n:
if nums[s] == val:
for j in range(s+1,n):
nums[j-1]=nums[j]
n -= 1
s -= 1
s += 1
return n
双指针法
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
fast=0
slow=0
lens =len(nums)
while fast<len(nums):
if nums[fast] != val:
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow