时隔两年又要开始刷LeetCode了,又忘差不多了,小菜鸡又来打打基础啦,听说y神的课很棒,就来听听学学做做笔记啦!
快排:随机选一个分界点x->调整区间:保证左边的都小于等于它,右边都大于等于它(swap)->递归处理左右两边。不稳定的。平均复杂度O(nlogn),因为选分界点时,不一定在中间,递归层数不一定是logn,但平均是logn
arr = [3,2,4,5,0,3]
def qsort(A,l,r):
if l >= r: return #边界
i, j = l-1, r+1 #双指针init
x = A[l] #用j递归则不能用r,用j不能用l
while i < j: #调整区间
i += 1 #do-while
while A[i]<x: i += 1
j -= 1
while A[j]>x: j -= 1
if i < j: A[i], A[j] = A[j], A[i]
qsort(A, l, j) #左右递归
qsort(A, j+1, r)
qsort(arr, 0, len(arr)-1)
print(arr)
# 另一个
n =int(input())
nums =list(map(int, input().split()))
def quick_sort(nums):
if(len(nums) <=1): return nums;
privot =nums[len(nums)//2]
left =[x for x in nums if x < privot]
mid =[x for x in nums if x == privot]
right =[x for x in nums if x> privot]
#print (" ".join(list(map(str, left))) +","+ str(mid[0]) +","+" ".join(list(map(str, right))) )
return quick_sort(left) +mid + quick_sort(right)
if __name__ =="__main__":
nums =quick_sort(nums)
print(" ".join(list(map(str, nums))))
归并排序:确定分界点(mid)->左右两边递归排序->把两个序列合二为一。稳定的。复杂度妥妥的O(nlogn),因为逐层分两半归并 总共logn层,一层内都是n(代价是需要额外空间)
n = int(input())
list1 = list(map(int, input().split()))
def merge_sort(list1):
if len(list1) <= 1:
return
mid = len(list1) // 2
L = list1[:mid]
R = list1[mid:]
merge_sort(L)
merge_sort(R)
i = j = k = 0
while i < len(L) and j < len(R):
if L[i] <= R[j]:
list1[k] = L[i]
i += 1
else:
list1[k] = R[j]
j += 1
k += 1
while i < len(L):
list1[k] = L[i]
k += 1
i += 1
while j < len(R):
list1[k] = R[j]
k += 1
j += 1
if __name__ == "__main__":
merge_sort(list1)
for i in list1:
print(i, end=" ")
二分查找:整数二分,两个模板,找“第一个target”要求左边x<tgt,右边x>=tgt,则用mid=(l+r)//2, r=mid, l=mid+1;找“最后一个target”则mid=(l+r+1)//2, l=mid, r=mid-1。做题时画图,尤其是判断等于的情况。例题:数的范围