文章总结:
文章链接:https://programmercarl.com/%E6%95%B0%E7%BB%84%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html
对于数组,其特点在于:
下标从0开始
内存空间的地址是连续的
在C++中对于int型整数(16进制)的存储如图:
注:在16进制中c代表12(8 + 4 = c)
题目总结:
704: 二分查找:
第一想法:
比较两个边界大小,当nums[l] < target时,l += 1, 当nums[r] > target时,r -= 1
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
l,r = 0, len(nums) - 1
while l < r:
if nums[l] < target:
l += 1
elif nums[r] > target:
r -= 1
if target == nums[l]:
return l
else:
return -1
缺点:速度较慢
二分法:
主要思路:找区间中间值,比较中间值与target的大小,再对于边界进行改变
难点:边界的控制(区间是否闭合,修改边界时是否-1)
闭区间:[left, right] (baseline)
left = right 时是有意义的 → while left <= right:
当left = right有意义时,面临的问题在于陷入死循环,所以我们要避开死循环 → 在修改边界时 l = middle + 1, r = middle - 1
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
l,r = 0, len(nums) - 1
while l <= r:
M = (l + r) // 2
if nums[M] < target:
l = M + 1
elif nums[M] > target:
r = M - 1
else:
return M
return -1
左闭右开区间:[left, right)
left = right没有意义 → while left < right:
left = right 没有意义就意味着我们在对于右边界修改时没有必要-1,因为nums[right]没有意义
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
l,r = 0, len(nums)
while l < r:
M = (l + r) // 2
if nums[M] < target:
l = M + 1
elif nums[M] > target:
r = M
else:
return M
return -1
注:注意r同时也要换成len(nums)因为区间变为了左闭右开
27:移除元素:
没有第一想法
快慢指针:
对于数组中元素的移除需要将后面的元素都向前移动,所以为了减少时间复杂度,对于暴力解法中的for循环的叠加需要去除。
改用快慢指针:
当fast指针的数值与val相等时,需要将fast指针前移
实际上就是利用fast指针向后寻找不等于目标值的数,然后前移
所以slow向前移动的条件是找到了不等于目标值的数
两个指针的用途:
slow:确定需要前移的位置
fast:寻找不等于val的数值
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
slow = 0
fast = 0
size = len(nums)
while fast < size:
if nums[fast] != val:
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow