作者最近跟着y总学习算法,在本专栏会不定期记录一些板子,语言主要是Python
本篇主要是快排,归并,二分
快速排序 手写快排主要是解决第k个数字的问题
def qs(q,l,r):
if l==r:
return
i,j = l-1,r+1
x = q[l]
while(i<j):
i += 1
j -= 1
while(q[i]<x): i += 1
while(q[j]>x): j -= 1
if i<j:
q[i],q[j] = q[j],q[i]
qs(q,l,j,k)
qs(q,j+1,r,k)
- 确定标准点,在这里是左端点
- 第一次排序(1. 通过一趟排序将待排序的数据分割成两个部分,使得一部分的所有数据都比另外一部分的所有数据都要小。),双层while,不得不吐槽,这里确实不如c++写起来方便
- 递归
sort函数排序挺好用的,但是板子还是得背,如果不会高深的算法,在排序过程中查找,用这个还是很nice的。
归并排序
- 计算mid
- 递归到底层
- 创建一个中间数组
- 双指针来做直接插入排序
- 恢复数组
chatgpt这样说的:申请空间,设定两个指针,比较两个指针所指向的元素,选择较小的元素放入到合并空间,并移动指针到下一位置,重复这个过程直到某一指针到达序列尾,然后将另一序列剩下的所有元素直接复制到合并序列尾。
def megret_sort(s,l,r):
if l>=r:
return
mid = (l+r)//2
megret_sort(s,l,mid)
megret_sort(s,mid+1,r)
i=l
j=mid+1
m = []
while(i<=mid and j<r+1):
if s[i]<=s[j]:
m.append(s[i])
i += 1
else:
m.append(s[j])
j += 1
while(i<=mid):
m.append(s[i])
i += 1
while(j<r+1):
m.append(s[j])
j += 1
for i in m:
if l<=r:
s[l] = i
l += 1
逆序对
用归并来计算逆序对真的太绝了
def megret_sort(a,l,r):
global k
if l>=r:return
mid = l+r >> 1
megret_sort(a,l,mid),megret_sort(a,mid+1,r)
i,j = l,mid+1
m = []
while(i<=mid and j<=r):
if a[i]<=a[j]:m.append(a[i]);i+=1
else:m.append(a[j]);k+=(mid-i+1);j+=1
while(i<=mid):m.append(a[i]);i+=1
while(j<=r):m.append(a[j]);j+=1
index = l
for i in m:
a[index] = i
index += 1
megret_sort(a,0,n-1)
二分
这里写了两个,一个是计算左边节点的,一个是计算右边节点,注意在计算右节点加1,主要是为了防止数组越界。
chat说的:从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一部分确定不可能有要查找的元素,那么就在另一部分继续这种搜索,直到找到要查找的元素,或者搜索结束发现数组中没有这样的元素。
l,r = 0,n-1
while(l<r):
mid = l+r >> 1
if arr[mid]>=x:
r = mid
else:
l = mid+1
if arr[l]!=x:
print("-1 -1")
continue
else:
print(l,end=" ")
l,r = 0,n-1
while(l<r):
mid = l+r+1 >> 1
if arr[mid]<=x:
l = mid
else:
r = mid-1
数的三次方根
这个真的很经典,真的想不到居然可以用差值来做精度。太久可了
n = float(input())
# print(f"{pow(n,1/3):.6f}")##不能计算负数
if n!=0:
l,r = -10000,10000
while(r-l>1e-7):
mid = (l+r)/2
if pow(mid,3)>=n:
r = mid
else:
l = mid
print(f"{l:.6f}")