【学习笔记】数据结构和常用算法 - Day1

视频简介

伪代码

用介于自然语言和计算机语言之间的文字和符号来描述算法,不属于任何一种语言,可翻译为程序员自身熟悉的语言

大厂面试必备

1.常用的数据结构;
2.常用的算法

算法的时间复杂度

什么是时间复杂度

定义:算法的执行效率、算法的执行时间与算法的输入值之间的关系;一般是看有没有循环结构;好的代码应尽量降低时间复杂度。

表示方法:大O表示法

具体案例

1.时间复杂度O(1),执行时间与输入值 num 无关

def O1(num):
	i = num
	j = num*2
	return i+j

2.时间复杂度O(N),主要看 for 循环

def ON(num):
	total = 0
	for i in range(num):
		total += i
	return total

3.时间复杂度O(logN),循环次数是 log2N

def OlogN(num):
	i = 1
	while (i<num):
		i = i*2
	return i

4.时间复杂度O(M+N)

def OMN(num1,num2):
	total = 0
	for i in range(num1):
		total += i
	for j in range(num2):
		total += j
	return total

5.时间复杂度O(NlogN)

def ONLogN(num1,num2):
	total = 0
	j = 0
	for i in range(num1):
		while (j<num2):
			total += i+j
			j = j*2
	return total

6.时间复杂度O(N²)

def ON2(num):
	total = 0
	for i in range(num):
		for j in range(num):
			total += i+j
	return total

常见的时间复杂度对比

在这里插入图片描述

算法的空间复杂度

什么是空间复杂度

定义:算法存储空间与输入值之间的关系;好的代码应尽量降低空间复杂度。

表示方法:大O表示法

具体案例

左边:O(1),右边:O(N)
在这里插入图片描述

判断空间复杂度的方法

1.若变量长度是1(整数、字符串等),空间复杂度是O(1);若变量长度与输入值N相关(列表、数组等),则空间复杂度是O(N);

2.递归结构占用的空间复杂度是O(N)。

常见的空间复杂度对比

O(1) < O(N) < O(N²)

时间复杂度和空间复杂度的关系

一般而言,两者只能二选一,需要进行取舍;
面试时可以根据面试官的偏好,选择时间 / 空间复杂度较低的算法;
工作时:时间 > 空间。

数据结构 - 数组 array

定义

连续的存储空间中,存储一组相同类型的元素。

数组访问和数组搜索

数组访问:通过索引访问元素
数组搜索:搜索某元素

数组的时间复杂度(重要)

访问:O(1)
原因:可以准确地访问索引对应的内存地址;

搜索:O(N),N是数组的长度
原因:无法得知被搜索元素的位置,只能从头开始寻找;

插入:O(N)
原因:最坏情况下:(1)需要在数组开头插入新元素时,需要将原元素全部往后移一位;(2)内存空间不够时,需要把原元素全部转移到新的内存地址,再插入新元素;

删除:O(N)
原因:最坏情况下,删除首元素时,需要将后面的元素全部往前移一位。

由上述总结:数组适合读,不适合写。

数组常用操作

创建数组

a = []

添加元素

# 尾部添加
a.append(1)

#时间复杂度:
#(1)内存空间足够时:O(1)
#(2)内存空间不足时:O(N)
# 中间插入
# 在索引2的位置添加元素99
a.insert(2,99)

# 时间复杂度:O(N)

访问元素

temp = a[2]

# 时间复杂度:O(1)

更新元素

a[2] = 88

# 时间复杂度:O(1)

删除元素

# 删除元素88
a.remove(88)
# 时间复杂度:O(N)

# 删除索引1的元素
a.pop(1)
# 时间复杂度:O(N)

# 删除最后一个元素
a.pop()
# 时间复杂度:O(1)

获取数组长度

size = len(a)

遍历数组

for i in a:
	print(i)

for index,element in enumerate(a):
	print('index at',index,'is',element)

for i in range(len(a)):
	print('i:',i,'element:',a[i])

# 以上3种方法的时间复杂度都是O(N)

查找元素

# 返回元素2的索引
index = a.index(2)

# 时间复杂度:O(N)

数组排序

# 升序
a.sort()

# 降序
a.sort(reverse = True)

# 时间复杂度:O(NlogN)

数据结构 - 链表 linked list

链表可以在不连续的存储空间中存储数据,充分利用了零碎的内存空间。

链表分为单端链表(常用)和双端链表,单端链表每部分除了数据外,还包括了 next 指针,而双端链表在单端链表基础上增加了 previous 指针。

时间复杂度

访问:O(N)
搜索:O(N)
插入(不包括寻找插入位置):O(1),不用移动插入位置后面的元素
删除(不包括寻找删除位置):O(1),不用移动删除位置后面的元素

特点

写很快,读很慢,读少写多。

链表常用操作

1.创建

linkedlist = deque()

2.添加元素

# 尾部插入:O(1)
linkedlist.append(1)

# 中间插入:O(N)
linkedlist.insert(2,99)

3.访问元素

# O(N)
element = linkedlist[2]

4.搜索元素

# O(N)
index = linkedlist.index(99)

5.更新元素

# O(N)
linkedlist[2] = 88

6.删除元素

# 以下操作都是O(N)

# 删除对应索引的值
del linkedlist[2]

# 删除某值
linkedlist.remove(88)

7.长度

# O(1),直接返回系统中存储的长度值
length = len(linkedlist)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值