1.数组理论
1.1定义:数组是存放在连续内存空间上的相同类型数据的集合。
因为数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址。
数组的元素是不能删的,只能覆盖。
1.2 那么二维数组在内存的空间地址是连续的么?
不同编程语言的内存管理是不一样的,在C++中二维数组是连续分布的。
像Java是没有指针的,同时也不对程序员暴露其元素的地址,寻址操作完全交给虚拟机。
Python也是连续的:
# 创建一个二维数组
matrix = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
# 遍历二维数组并输出每个元素的内存地址
for row in matrix:
for element in row:
print(f"Element {element} 的内存地址是:{id(element)}")
#####输出结果#####
Element 1 的内存地址是:4360497968
Element 2 的内存地址是:4360498000
Element 3 的内存地址是:4360498032
Element 4 的内存地址是:4360498064
Element 5 的内存地址是:4360498096
Element 6 的内存地址是:4360498128
Element 7 的内存地址是:4360498160
Element 8 的内存地址是:4360498192
Element 9 的内存地址是:4360498224
2.今日题目
2.1 (704. 二分查找)
题目链接:https://leetcode.cn/problems/binary-search/
文章讲解:https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html
视频讲解:https://www.bilibili.com/video/BV1fA4y1o715
二分法的前提条件:数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的
思路:区间的定义就是不变量。要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是循环不变量规则。
解法:左闭右闭即[left, right]
lass Solution:
def search(self, nums: List[int], target: int) -> int:
left=0
right=len(nums)-1
while left<=right:
middle = left+(right-left)//2
if nums[middle]>target:
right=middle-1
elif nums[middle]<target:
left=middle+1
else:
return middle
else:
return -1
2.2 (27. 移除元素)
题目链接:https://leetcode.cn/problems/remove-element/
文章讲解:https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html
视频讲解:https://www.bilibili.com/video/BV12A4y1Z7LP
思路:
1.暴力解法就是每个元素与val比较时进行元素覆盖,后面的元素向前覆盖
class Solution:
def removeElement(self, nums: List[int], val: int) -> 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
else:
i += 1
return size
2.双指针,我们的新数组就是去除val的值,搞两套下标,因为数组是可覆盖的,快指针负责找元素,慢指针负责将快指针的元素覆盖到位置上
双指针法(快慢指针法)在数组和链表的操作中是非常常见的,很多考察数组、链表、字符串等操作的面试题,都使用双指针法。
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
size = len(nums)
slow = 0
for i in range(0, size):
if nums[i] != val:
nums[slow] = nums[i]
slow += 1
return slow