@代码随想录 day1:数组二分查找,移除元素
数组是存放在连续内存空间上的相同数据的集合。
a.下表从0开始
b.数组内存空间连续
arr = [1, 2, 3]
for x in arr:
print(id(x))
#1606773504
#1606773536
#1606773568
数组arr中各个元素地址之间间隔32,这是因为Python中的整数对象是以固定大小表示的。
在CPython解释器中,小整数(-5到256)是以单字长(32位)存储的,占用4个字节的内存空间。整数对象是不可变的,每创建一个新整数,都会分配新的内存空间。
数组包含3个小整数1,2,3。当遍历数组并打印每个元素地址时,它们之间正好相差4个字节(32位),也就是32。
写二分法,区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right)。
#day1 二分法
#doudou 2023.7.12
'''
1.左闭右闭
2.左闭右开
'''
nums = [-1,0,3,5,9,12]
target = 9
#左闭右开
left=0
right=len(nums)
#右开,故不能=right
while left<right:
#//表示整数除法
middle=left+(right-left)//2
if target<nums[middle]:
right=middle
elif target>nums[middle]:
#左边闭合,所以判断力已经比较过中间值,更新从+1开始
left=middle+1
else:
print(middle)
break
#左闭右闭
# left=0
# right=len(nums)-1
# while left<=right:
# middle=left+(right-left)//2
# if target
# right=middle-1
# elif target>nums[middle]:
# left=middle+1
# else:
# print(middle)
这里不能直接用return返回值,会报错:
SyntaxError: ‘return’ outside function
原因是return 关键字只能在 def 自定义函数里面使用,在 while 循环中只能使用 break 关键字来结束循环! 这里没有自定义函数,所以不能出现 return 这样的关键字!
自己写的暴力移除方法
'''
移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。
例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
'''
nums = [3,2,2,3]
val = 3
del_list=[]
for i in range(len(nums)):
if nums[i] ==val:
del_list.append(i)
#这里不能直接删除,每删除一次,元素下标都会发生变化
# for i in del_list:
# del(nums[i])
print(del_list)
for i in range(len(del_list)):
del_list[i]=del_list[i]-i
for i in del_list:
del(nums[i])
print(len(nums),'nums=',nums)
'''
力扣版
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
del_list=[]
for i in range(len(nums)):
if nums[i] ==val:
del_list.append(i)
#这里不能直接删除,每删除一次,元素下标都会发生变化
# for i in del_list:
# del(nums[i])
#print(del_list)
for i in range(len(del_list)):
del_list[i]=del_list[i]-i
for i in del_list:
del(nums[i])
return len(nums)
'''
以上方法虽然解决了问题,但是用到了额外的数组空间。
双指针法:
通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
定义快慢指针
快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
慢指针:指向更新 新数组下标的位置
nums = [3,2,2,3]
val = 3
slow=0
for fast in range(len(nums)):
if nums[fast]!=val:
nums[slow]=nums[fast]
slow+=1
print(nums)
print(slow)
'''
力扣代码
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
slow=0
for fast in range(len(nums)):
if nums[fast]!=val:
nums[slow]=nums[fast]
slow+=1
return slow
'''
#输出:[2, 2, 2, 3]
#2
元素的顺序可以改变,不需要考虑数组中超出新长度后面的元素。
好好学习,天天向上!
参考链接:https://programmercarl.com/%E6%95%B0%E7%BB%84%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html