python刷题记录
一、基础知识
1、进制转换
整数部分
进制表示:十进制直接表示,如 10;
二进制前面加0B,如 0B1010;
八进制前面加0o,如 0o12;
十六进制前面加0X,如 0XA;
# 十进制转其他进制
print(bin(10)) # 十进制转二进制
print(oct(10)) # 十进制转八进制
print(hex(10)) # 十进制转十六进制
0b1010
0o12
0xa
注意,输出的为字符串类型,要去掉前缀需使用切片[2:]
# 其他进制转十进制
print(int('0b1010',2)) # 二进制转十进制
print(int('0o12',8)) # 八进制转十进制
print(int('0xA',16)) # 十六进制转十进制
10
10
10
注意,前缀可带也可以不带,十六进制转十进制时,A-F字母大小写均可
其他进制类型转换可以先转十进制再转其他进制
小数部分
十进制转其他进制
计算(如0.3转二进制) | 值 |
---|---|
0.3 * 2=0.6 | 0 |
0.6*2=1.2 | 1 |
0.2*2=0.4 | 0 |
0.4*2=0.8 | 0 |
0.8*2=1.6 | 1 |
… | … |
所以十进制小数0.3转二进制小数位0.01001…
其他进制转十进制,如二进制0.01001转十进制
0 * (1/2) + 1*(1/4)+0*(1/8)+0*(1/16)+1*(1/32)= 0.28125
因为十进制转其他进制存在取不尽的情况,所以会有误差。
剑指 Offer 15. 二进制中1的个数
1290. 二进制链表转整数
1399. 统计最大组的数目
405. 数字转换为十六进制数(涉及补码)
2、补码
计算机原码
原码(true form)是一种计算机中对数字的二进制定点表示方法。原码表示法在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位为1(0有两种表示:+0和-0),其余位表示数值的大小。
我们用8位二进制表示一个数
+11的原码为00001011,-11的原码就是10001011
计算机补码
1、对于正数
正整数的补码是其二进制表示,与原码相同。
例:+9的补码是00001001。(备注:这个+9的补码是用8位2进制来表示的,补码表示方式很多,还有16位二进制补码表示形式,以及32位二进制补码表示形式,64位进制补码表示形式等。每一种补码表示形式都只能表示有限的数字。)
2、对于负数
求负整数的补码,将其原码除符号位外的所有位取反(0变1,1变0,符号位为1不变)后加1。
同一个数字在不同的补码表示形式中是不同的。比如-15的补码,在8位二进制中是11110001,然而在16位二进制补码表示中,就是1111111111110001。以下都使用8位2进制来表示。
例:求-5的补码。
-5对应带符号位负数5(10000101)→除符号位外所有位取反(11111010)→加00000001(11111011)
所以-5的补码是11111011。
0的补码
数0的补码表示是唯一的。
[+0]补=[+0]反=[+0]原=00000000
[ -0]补=11111111+1=00000000
二、基本数据结构
1、数组
数组类型主要有三个方法,二分法、双指针、滑窗
二分法:
704. 二分查找
34. 在排序数组中查找元素的第一个和最后一个位置
977. 有序数组的平方
双指针:
189. 轮转数组
2、队列
3、栈
4、链表
5、哈希表
6、字符串
三、二叉树
四、堆
五、图论
六、常用算法
1、递归
1、回溯
2、深度优先搜索
3、广度优先搜索
4、动态规划
5、分治
6、二分法
7、十大经典排序算法
冒泡排序
比较相邻的两个元素,如果前面的比后面的大,就交换两个元素的位置,从最开始一对到最后一对进行比较,直到没有任何一对需要比较,相当于每次把当前遍历的最大元素放到最后。
def bubblesort(arr):
for i in range(1, len(arr)):
for j in range(len(arr) - i):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
选择排序
首先在未排序序列中遍历找到最小(大)元素,然后存放到排序序列的起始位置。再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。重复第二步,直到所有元素均排序完毕。
def selectionsort(arr):
for i in range(len(arr) - 1):
minIndex = i
for j in range(i + 1, len(arr)):
if arr[j] < arr[minIndex]:
minIndex = j
if i != minIndex:
arr[i], arr[minIndex] = arr[minIndex], arr[i]
return arr
插入排序
将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
def insertionsort(arr):
for i in range(len(arr)):
preIndex = i-1
current = arr[i]
while preIndex >= 0 and arr[preIndex] > current:
arr[preIndex+1] = arr[preIndex]
preIndex-=1
arr[preIndex+1] = current
return arr
希尔排序
先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。
def shellsort(arr):
import math
gap=1
while gap < len(arr)/3:
gap = gap * 3 + 1
while gap > 0:
for i in range(gap, len(arr)):
temp = arr[i]
j = i - gap
while j >= 0 and arr[j] > temp:
arr[j + gap] = arr[j]
j -= gap
arr[j + gap] = temp
gap = math.floor(gap / 3)
return arr
归并排序
将序列每相邻两个数字进行归并操作,形成floor(n/2)个序列,排序后每个序列包含两个元素。将上述序列再次归并,形成floor(n/4)个序列,每个序列包含四个元素, 重复步骤,直到所有元素排序完毕
def mergeSort(arr):
import math
if(len(arr)<2):
return arr
middle = math.floor(len(arr)/2)
left, right = arr[0:middle], arr[middle:]
return merge(mergeSort(left), mergeSort(right))
def merge(left,right):
result = []
while left and right:
if left[0] <= right[0]:
result.append(left.pop(0))
else:
result.append(right.pop(0));
while left:
result.append(left.pop(0))
while right:
result.append(right.pop(0));
return result
快速排序
在数列之中,选择一个元素作为”基准”(pivot),或者叫比较值。数列中所有元素都和这个基准值进行比较,如果比基准值小就移到基准值的左边,如果比基准值大就移到基准值的右边,以基准值左右两边的子列作为新数列,不断重复前两步,直到所有子集只剩下一个元素为止。
def quick_sort(barr):
if len(arr) < 2:
return arr
mid = arr[len(arr) // 2]
left, right = [], []
arr.remove(mid)
for item in arr:
if item >= mid:
right.append(item)
else:
left.append(item)
return quick_sort(left) + [mid] + quick_sort(right)