初学算法第一课(主要记录y总板子)

57 阅读3分钟

作者最近跟着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}")