数组
- 数组下标都是从0开始的。
- 数组内存空间的地址是连续的
数组在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址。
二分法
给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -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 = (right + left) // 2
if target > nums[mid]:
left = mid
elif target < nums[mid]:
right = mid
elif target == nums[mid]:
return mid
return -1
这样就会陷入超时,例如当 left = 1,right = 2时,mid = 1,若此时 mid 的位置上的值小于 target,则代码会陷入无限循环,更新后的 left 始终为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 = (right + left) // 2
if target > nums[mid]:
left = mid + 1
elif target < nums[mid]:
right = mid - 1
elif target == nums[mid]:
return mid
return -1
使用 mid + 1 或 mid - 1 来作为更新后的 left 或者 right 可以避免这个问题。
需注意 while 的条件为 left <= right,如果设为 left < right 则针对长度为1的数组无法执行。使用左闭右开可以解决这一问题,但代码需要做如下调整 (即 right 整体加1):
class Solution:
def search(self, nums, target):
left, right = 0, len(nums)
while left < right:
mid = (right + left) // 2
if nums[mid] > target:
right = mid
elif nums[mid] < target:
left = mid + 1
else:
return mid
return -1
移除元素
给你一个数组 nums
和一个值 val
,你需要原地移除所有数值等于 val
的元素。元素的顺序可能发生改变。然后返回 nums
中与 val
不同的元素的数量。
假设 nums
中不等于 val
的元素数量为 k
,要通过此题,您需要执行以下操作:
- 更改
nums
数组,使nums
的前k
个元素包含不等于val
的元素。nums
的其余元素和nums
的大小并不重要。 - 返回
k
。
暴力法
暴力法不能直接使用 for loop,因为数组每次去掉值时需要被全部更新,因此需要使用 while loop。
每次找到 val 时,size 所代表的数组长度 - 1,同时因为 i 以后的数值都向前移动了一位,所以 i 也向前移动一位。
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
size = len(nums)
i = 0
while i < size:
if nums[i] == val:
for j in range(i + 1, size):
nums[j - 1] = nums[j]
size -= 1
i -= 1
i += 1
return size
双指针法
双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
- 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组,即如果 fast 位置上的数值不为 val,将数组 slow 位置的数值设为 fast 位置数值。
- 慢指针:指向更新,新数组下标的位置,为新数组的有效长度。
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
fast = 0
slow = 0
size = len(nums)
while fast < size:
if nums[fast] != val:
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow