本文主要介绍数据结构与算法的知识点,包括线性表、数组和广义表、栈和队列、树和二叉树、图、查找、排序等,如有不当之处,敬请指正,感谢各位大佬!有些问题不免解释不全面或者暂时未回答(先留坑),欢迎各位读者踊跃解答哈!
数据结构
线性表
栈和队列
字符串
1. 写最大串匹配算法
数组和广义表
树存储结构
1. 二叉树深度优先遍历的递归和循环实现
2. 二叉树层次(广度)遍历
3. 求完全二叉树节点数方法1:当做普通二叉树,递归求解;
方法2:根据完全二叉树左右深度是否相等进行,若相等则用公式计算节点数,若不相等则继续递归。
图存储结构
查找表结构
1. 写二分查找
2. Hash冲突解决方法开放定址法:线性探测法:d=1,2,3,…,m-1
二次探测法:d=12,-12,22,-22,32,…
伪随机数探测法:d=伪随机数
再哈希法
链地址法
建立一个公共溢出区
排序算法
1. 写快速排序
2. 写堆排序算法C++中,set和multiset都是基于红黑树实现,查找、删除、插入操作都只需O(logk)时间。
基础理论
1. 理解递归
基础算法
1. 找链表倒数第k个节点
2. 从尾到头打印链表
3. n阶台阶每次只能跨一步或两步,求路径总数。动态规划,从上到下分析问题,从下到上编码实现。
4. 已知两矩形的x1,y1,x2,y2,求交集面积。
x11, y11, x12, y12 = []
x21, y21, x22, y22 = []
def calc_intersection(bbox1, bbox2):
"""calc_intersection"""
xmingt, ymingt, xmaxgt, ymaxgt = bbox1
xminpre, yminpre, xmaxpre, ymaxpre = bbox2
xmin = max(xmingt, xminpre)
ymin = max(ymingt, yminpre)
xmax = min(xmaxgt, xmaxpre)
ymax = min(ymaxgt, ymaxpre)
w = xmax - xmin
h = ymax - ymin
if w <= 0 or h <= 0:
return 0
return w * h
5. n+1长的无序数组,数分布为1~n,只有1个数重复,找出重复数;要求:不能改原数组,空间复杂度<=o(1),时间复杂度<=o(n)方法1:求数组中重复元素 位操作。所有元素逐个求异或操作,再与range(1,n)的数字逐个求异或操作;所得结果为重复数字与n+1的异或结果,可反推出唯一重复数字。
方法2:数值二分法。统计数值区间中,数的个数;如数值区间[1,n/2](不是数组下标值的二分)中,数的个数是否大于n/2个,大于则此区间内必有重复数;继续数值二分,直到找到该数。
def search_duplication(array):
"""search_duplication"""
n = len(array)
if n > 1:
xor_res = None
for a in array + list(range(1, n+1)):
xor_res ^= a
return xor_res ^ n
return None
6. n*n矩阵,逆时针旋转90度。
# coding: utf-8
def rotation90_anticw(arr, n, res):
"""rotation90_anticw"""
if n == 0 or not arr:
return
if not len(res) == n or not len(res[0]) == n:
return
r, c = 0, 0
for jj in range(n-1, -1, -1):
c = 0
for ii in range(0, n):
res[r][c] = arr[ii][jj]
c += 1
r += 1
return res
if __name__ == '__main__':
n = 5
arr = [[1,2,3,4,5],
[6,7,8,9,10],
[11,12,13,14,15],
[16,17,18,19,20],
[21,22,23,24,25]]
res = [[-1,-1,-1,-1,-1],
[-1,-1,-1,-1,-1],
[-1,-1,-1,-1,-1],
[-1,-1,-1,-1,-1],
[-1,-1,-1,-1,-1]]
print(rotation90_anticw(arr, n, res))
7. a, b两数组里面都存放不重复的int数,但a和b有重复数,找出。
8. 判断两个字符串是否模式一致两个字符串中包含多个单词,单词与单词用空格隔开,判断两个字符串是否模式一致。模式一致定义为重复和不重复单词出现的位置一致。
模式一致样例:A = 'hey hey I am your brother, hey'
B = 'oh oh you are here ? oh'
模式不一致样例:A = 'X Y X Y Z'
B = 'P Q P Q R'
def is_same_pattern(A, B):
a_parts = A.split(' ')
b_parts = B.split(' ')
if len(a_parts) != len(b_parts):
return False
words_dict_a = {}
words_dict_b = {}
idx_a = 0
idx_b = 0
for ii in range(len(a_parts)):
# a
if a_parts[ii] not in words_dict_a.keys():
words_dict_a[a_parts[ii]] = idx_a
idx_a += 1
# b
if b_parts[ii] not in words_dict_b.keys():
words_dict_b[b_parts[ii]] = idx_b
idx_b += 1
# judge
if words_dict_a[a_parts[ii]] != words_dict_b[b_parts[ii]]:
return False
return True
9. 数组按个位数排序
10. 计算1到n每个数的阶乘求和
11. 手环有十项运动,根据用户点击次数进行智能排序;需要什么数据;排序用的数学模型是什么
编程语言
C++
1. C++11新特性,5个
2. STL中vector和map区别vector是连续地址存储,三个指针指向first,last,end;
map是键值对序列,可以用平衡二叉树存储;
3. set/multiset, map/multimap使用set或multiset之前,必须加入头文件;
set、multiset都是集合类,差别在与set中不允许有重复元素,multiset中允许有重复元素;
sets和multiset内部以平衡二叉树(红黑树)实现。
sets和multiset可以看成一个序列,查找、插入、删除一个数都能够在O(logn)的时间内完成,而且他能时刻保证序列中的数是有序的。
set c; // 创建空集合,不包含任何元素set c(op); // 以op为排序准则,产生一个空的setset c1(c2); // 复制c2中的元素到c1中set c(const value_type *first, const value_type* last); // 复制[first, last)之间元素构成新集合set c(const value_type *first, const value_type* last,op); // 以op为排序准则,复制[first, last)之间元素构成新集合。c.~set(); // 销毁所有元素,释放内存
multiset mc; // 创建空集合,不包含任何元素multiset mc(op); // 以op为排序准则,产生一个空的setmultiset c1(c2); // 复制c2中的元素到c1中multiset c(const value_type *first, const value_type* last); // 复制[first, last)之间元素构成新集合multiset c(const value_type *first, const value_type* last,op); // 以op为排序准则,复制[first, last)之间元素构成新集合。c.~set(); // 销毁所有元素,释放内存
4. 各个常用数据容器的特点,优缺点及适用场景数组、链表、二叉搜索树、平衡二叉树(AVL树)
最大堆最小堆数据结构插入的时间复杂度得到中位数的时间复杂度
没有排序的数组O(1)O(n)
排序的数组O(n)O(1)
排序的链表O(n)O(1)
二叉搜索树平均O(logn),最差O(n)平均O(logn),最差O(n)
AVL树O(logn)O(1)
最大堆最小堆O(logn)O(1)
5. make_heap(), pop_heap(), push_heap()make_heap()是生成一个堆,大顶堆或小顶堆make_heap(_RAIter,_RAIter) # 默认生成大顶堆
make_heap(_RAIter,_RAIter,_Compare) # _Compare有两种参数,一种是greater(生成小顶堆),一种是less(生成大顶堆)
push_heap()是向堆中插入一个元素,并且使堆的规则依然成立push_heap(_RAIter,_RAIter) # 默认为大顶堆
push_heap(_RAIter,_RAIter,_Compare) # _Compare有两种参数,一种是greater(小顶堆),一种是less(大顶堆)
调用push_heap之前必须调用make_heap创建一个堆
首先数组push_back插入元素,然后再调用push_heap,它会使最后一个元素插到合适位置
注意,push_heap中的_Compare和make_heap中的_Compare参数必须是一致的,不然会插入堆失败,最后一个元素还是在最后位置,导致插入失败
pop_heap()是在堆的基础上,弹出堆顶元素pop_heap(_RAIter,_RAIter) # 默认为大顶堆
pop_heap(_RAIter,_RAIter,_Compare) # _Compare有两种参数,一种是greater(小顶堆),一种是less(大顶堆)
比如pop_heap(nums.begin(), nums.end(),greater()),它会将堆顶元素(即为数组第一个位置)和数组最后一个位置对调,然后你可以调用数组pop_back,删除这个元素
注意,pop_heap中的_Compare和make_heap中的_Compare参数必须是一致的,不然会失败
6. 比较仿函数less和greater
sort(vec.begin(), vec.end(), less());
push_heap(nums.begin(), nums.end(), greater());
pop_heap(nums.begin(), nums.end(), greater());
7. C++常见问题
Python
1. python函数的值传递、引用传递什么时候发生值传递就发生在实参为不可变对象时,而引用传递发生在实参为可变对象时。不可变对象:如 数字,元组,字符串;
可变对象:如 列表,字典。
在值传递中,不改变形式参数的值,而在引用传递中,形式参数的值是被改变的。
2. python的type和objecttype可以实例化所有类,包括object;
object是所有类的父类,包括type;
type.__new__:type.__new__()调用的是type类的类方法__new__或者静态方法__new__
type()是使用type的__init__()方法新建一个type实例或者调用type类的静态__call__()方法或者类方法__call__()
(典型的就是求一个对象的类型type("Hello"))type(object) -> the object's type
type(name, bases, dict) -> a new type
3. python的虚函数、抽象方法、metaclass元类;
4. 目录下所有文件如何遍历?
os.walk()默认以topdown方式递归遍历根文件夹及其子文件夹。
5. str.split(sep),sep是空格, \t, 还是正则
6. 读取大文件,求最大值,最小值,均值,方差
# data.txt
# cat_id num
# ......
# cat_id min, max, mean, sample_variance
form collections import defaultdict
def read_file(file_path):
assert os.path.exist(file_path)
with open(file_path) as f:
for line in f.readline():
# split(sep) sep .strip()
cat_id, num = line.split().strip()
yield (int(cat_id), float(num))
def statistics(file_path):
table = defaultdict(list)
for cat_id, num in read_file(file_path):
if table.get(cat_id, None):
min_val, max_val, mean_val, var_val, N = table[cat_id] # N is samples number of cat_id
new_min_val = min_val if min_val < num else num
new_max_val = max_val if max_val > num else num
# >> 1
new_mean_val = (mean_val + num) >> 1
new_var_val = ((var_val * (N - 1)) + (num - new_mean_val) ** 2)) / N
table[cat_id]= [new_min_val, new_max_val, new_mean_val, new_var_val, N + 1]
else:
table[cat_id] = [num, num, num, 0, 1]
return table
操作系统
1. linux删除后空间未释放
2. 查找端口号为8080的进程
3. sed字符串替换