基础
数组
数组是存放在连续内存空间上的相同类型数据的集合。
![](https://img-blog.csdnimg.cn/img_convert/66aeee37729273500bfe5d0a9427178e.png)
需要注意两点:
数组的下标都是从0开始。
数组内存空间的地址是连续的
正是因为数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址。
数组的元素是不能删的,只能覆盖。
二维数组
# 创建二维数组
def CreateaArray(w, h):
arr = []
for y in range(h):
line = []
for x in range(w):
line.append(0)
arr.append(line)
return arr
def show(arr):
for line in arr:
print(line)
def main():
a1 = CreateaArray(11,11)
show(a1)
if __name__ == '__main__':
main()
2.时间复杂度
时间复杂度:用来评估算法运行的效率的式子->O(),O:数学中的上界,理解为大约,n:单位(类似秒),可以将加减乘除print等基本操作简单理解为1个运行单位n=1。
一般来说,时间复杂度高的算法比低的慢。
常见的时间复杂度(按照效率排序)
![](https://img-blog.csdnimg.cn/img_convert/c01a4af7273007e7d1d3a195feaf687f.png)
复杂问题的时间复杂度
![](https://img-blog.csdnimg.cn/img_convert/5dae67adb7eb38bb16789ea7b19b6697.png)
print("hello,world")------------O(1)
# n 问题规模,n的大小影响算法的复杂情况
for i in range(n):
print("hello,world")-----------O(n)
for i in range(n):
for j in rang(n):
print("hello,world")-----------O(n**2)
for i in range(n):
for j in rang(n):
for k in rang(n):
print("hello,world")-----------O(n***3)
while n > 1:
print(n)
n = n//2
n = 64
输出:64、32、16、8、4、2
时间复杂度:O(log2n)O(logn)----------->以2为底n的对数
当循环出现减半的时候,一定会出现logn的时间复杂度。
3.如何简单快速判断算法复杂度
确定问题规模n;
循环减半->logn;
k层关于n的循环->几层循环就是n的几次方
4.空间复杂度
用来评估算法内存占用大小的式子
表达方法与时间复杂度完全一样
算法使用了几个变量:O(1);
算法使用了长度为n的一维列表:O(n);
算法使用了m行n列的二维列表:O(mn);
数组
二分查找
也叫折半查找,从有序列表的初始候选区li[o, n]开始,通过对待查找的值与候选区中间值(留下的数据,需要查找的值可能出现的位置)的比较,可以使候选区键少一半。
思路
给定一个有序列表 lis = [1,2,3,4,5,6,7,8,9],tarket = 3。列表为左闭右闭
1、确定左右边界
left、right = 0, len(lis) - 1
2、确定中间值、索引
mid = (left + right) // 2 lis[mid] = 5 > tarket
3、候选区
说明候选区在mid左边,right = mid -1 候选区left:right = [0: 3]
mid = (0 + 3) //2 = 1 lis[1] = 2 < 3
说明候选区在mid右边,left = mid + 1 候选区left: right = [2 : 3]
mid = (2 + 3) //2 = 2 此时 lis[2] = 3,找到tarket
另外:如果mid = 2, lis[2] > tarket, 说明候选区还在mid左边,此时right = mid - 1 = 1,
left = 3,已经找不到target,所以确保候选区右tarket,必须left <= right
代码实现
def b_search(nums, tarket):
"""
:param nums: list
:param target:int
:return: [index, index]
"""
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == tarket:
return mid
elif nums[mid] > tarket:
right = mid -1
else:
left = mid + 1
else:
return -1
时间复杂度
O(logn)
移除元素
思路
双指针法(快慢指针法):通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
定义快慢指针
快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
慢指针:指向更新 新数组下标的位置
代码实现
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
# 快慢指针
fast = 0 # 快指针
slow = 0 # 慢指针
size = len(nums)
while fast < size: # 不加等于是因为,a = size 时,nums[a] 会越界
# slow 用来收集不等于 val 的值,如果 fast 对应值不等于 val,
#则把nums[fast]赋值给nums[slow]
if nums[fast] != val:
nums[slow] = nums[fast]
slow += 1
# 如果fast对应的值等于val,则不给nums[slowly]赋值,slowly不动,fast继续向前寻找新值
fast += 1
return slow
时间复杂度
O(n^2)