建筑行业工作党终于下定决心转算法了!忍不了了。。感觉自己基础不扎实,项目做了不少,但题基本上没刷过,希望能在代码随想录里面把自己的基础打牢一点,offer早早来!
数组理论基础
https://programmercarl.com/%E6%95%B0%E7%BB%84%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html
- 数组下标都是从0开始的。
- 数组内存空间的地址是连续的
- 数组元素不能删除,只能覆盖
- 不同语言的内存管理不同,比如C++上二维数组是空间连续的,在java上不是
704. 二分查找
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left=0
right=len(nums)-1
mid=(left+right)/2
while target < nums[mid]:
right = mid
while target > nums[mid]:
left = mid+1
return mid
然后瞟了一眼答案,写成了这样,还是错的。怀疑是边界处理的问题,仔细想了一下我这里是左闭右开的区间,left<right是包含了所有的列表情况了
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left=0
right=len(nums)-1
while left < right: # 有不止一个元素
mid=(left+right)/2
if target < nums[mid]:
right = mid
elif target > nums[mid]:
left = mid+1
else:
return mid
else: # 只有一个元素
return 0
所以改成了这样,提交后发现又错了。检查了一下,发现是right的写法有问题
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left=0
right=len(nums)-1
while left < right: # 这里已经包含了所有左开右闭列表,是全集
mid=(left+right)/2
if target < nums[mid]:
right = mid
elif target > nums[mid]:
left = mid+1
else:
return mid
else: # 如果查不到,说明这个值不在列表里
return -1
终于提交通过了!
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left=0
right=len(nums) # 左闭右开,右边界是没包进去的,所以这里不需要减一
while left < right: # 左闭右开,只有这种情况合法
mid=left+(right-left)/2
if target < nums[mid]:
right = mid
elif target > nums[mid]:
left = mid+1
else:
return mid
return -1 # 查找失败
迅速写了一下左闭右闭,顺利通过:
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left=0
right=len(nums)-1
while left <= right:
mid=left+(right-left)/2
if target < nums[mid]:
right = mid-1
elif target > nums[mid]:
left = mid+1
else:
return mid
return -1 # 查找失败
27.移除元素
题目链接在这里:https://leetcode.cn/problems/remove-element/description/
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
for i in range(len(nums)-1):
if nums[i]==val:
for j in range(len(nums)-i-1):
nums[i+j] = nums[i+j+1]
return len(nums)
对了4遍答案后写成了这样,还是错了。又仔细一遍遍答案,发现我有两个for循环,但是其实答案并没有真的写两个for循环,而是用if条件语句和i+=1替代了。我发现第一个for循环不能像我这样写,因为e是变化的。
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
s = 0
e = len(nums)
while s < e: # 全集
for i in range(e): # range函数是左闭右开的,所以右边界取最后一个元素的下标+1
if nums[i]==val:
for j in range(i+1,e):
nums[j-1] = nums[j]
e-=1
i-=1 # 感觉就是覆盖,并且长度-1
i+=1 # 不需要删就让指针往前走
return e # 等于的情况就只有一个元素
又改了两遍,第一个用while动态循环,把s换成了i,终于通过了
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
i = 0
e = len(nums)
while i < e: # 指针还在移动的时候
if nums[i]==val:
for j in range(i+1,e):
nums[j-1] = nums[j]
e-=1
i-=1 # 感觉就是覆盖,并且长度-1
i+=1 # 不需要删就让指针往前走
return e # 等于的情况就只有一个元素
然后来写双指针法:
一开始写成这样,提示index out of range,没有跑通。乍一看是对的,后来发现这个!=判断应该用if,因为如果不在现在的while循环里写f+=1,那就会在while循环里出不来,如果写了,就出现f每次走两格了。
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
s = 0
for f in range(len(nums)):
while nums[f] != val:
nums[s] = nums[f]
s+=1
return s
修改后提交通过了!赶在十二点之前呜呜
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
s = 0
for f in range(len(nums)):
if nums[f] != val:
nums[s] = nums[f]
s+=1
return s