在b站上跟着左程云老师的课程学,这里简单记录一下每次课程学的代码。本人超级新手,很期待和大家共同讨论!
一、入门
1、二进制与位运算
#下面我们设计一个将十进制数转换成二进制的代码,要求二进制位数不超过32位
#import numpy as np
def print_binary(num):
result = '' #为使最终输出结果为一列字符串
for i in range(31,-1,-1):
a = num & (1 << i)
if a == 0:
result +='0'
else:
result +='1'
print(result)
自己摸的,看起来不是很简洁。
#chatgpt给的写法
def print_binary(num):
for i in range(31, -1, -1):
# 下面这句写法,可以改成 :
# print("1" if (num & (1 << i)) != 0 else "0", end="")
# 但不可以改成 :
# print("1" if (num & (1 << i)) == 1 else "0", end="")
# 因为num如果第i位有1,那么(num & (1 << i))是2的i次方,而不一定是1
# 比如,num = 0010011
# num的第0位是1,第1位是1,第4位是1
# (num & (1<<4)) == 16(不是1),说明num的第4位是1状态
print("1" if (num & (1 << i)) != 0 else "0", end="")
print()
# 示例用法
num = -19
print_binary(num)
print(..., end='')表示用''替代换行符'\n',从而使最终输出一串字符串,最后的print()输入一个'\n',使得即便连续调用print_binary(),也不会出现一大串数字。
2、三傻排序:选择、冒泡与插入
选择排序:
def swap(arr, i, j):
arr[i], arr[j] = arr[j], arr[i]
#选择排序
def selection_sort(arr):
if arr is None or len(arr) < 2:
return
for i in range(len(arr) - 1):
min_index = i
for j in range(i + 1, len(arr)):
if arr[j] < arr[min_index]:
min_index = j
swap(arr, i, min_index)
冒泡排序:
#冒泡排序, 自编版
def swap(arr, i, j):
arr[i], arr[j] = arr[j], arr[i]
def bubbleSort(arr):
if arr == None or len(arr) < 2:
return
for i in range(len(arr)-1):
for j in range(len(arr)-i-1):
if arr[j] > arr[j+1]:
swap(arr, j, j+1)
print(arr)
#冒泡排序, chatgpt版
def swap(arr, i, j):
arr[i], arr[j] = arr[j], arr[i]
def bubble_sort(arr):
if arr is None or len(arr) < 2:
return
for end in range(len(arr) - 1, 0, -1):
for i in range(end):
if arr[i] > arr[i + 1]:
swap(arr, i, i + 1)
插入排序:
#插入排序, 自编版
def swap(arr, i, j):
arr[i], arr[j] = arr[j], arr[i]
def insertionSort(arr):
if arr == None or len(arr)<2:
return
for i in range(1, len(arr)):
for j in range(i-1, -1, -1):
if arr[j+1] < arr[j]:
swap(arr, j, j+1)
else:
break
print(arr)
#插入排序, chatgpt版
def swap(arr, i, j):
arr[i], arr[j] = arr[j], arr[i]
def insertion_sort(arr):
if arr is None or len(arr) < 2:
return
for i in range(1, len(arr)):
j = i - 1
while j >= 0 and arr[j] > arr[j + 1]:
swap(arr, j, j + 1)
j -= 1
3、检验利器:对数器
#下面以上节的三傻排序为例写一个对数器,本质思想是生成随机数组对多种代码跑出来的结果进行对比
#自编版对数器
import numpy as np
#N:生成随机数组的最大长度,V:随机数组的元素取值范围[0,V),test_times:测试次数
def Validator(N, V, test_times):
print('测试开始')
for i in range(test_times):
n = np.random.randint(N)+1 #生成一个随机长度,范围是1~N
arr = np.random.randint(V, size = n) #生成随机数组,元素取值范围[0,V)中的整数
arr1 = arr
arr2 = arr
arr3 = arr
selection_sort(arr1)
bubble_sort(arr2)
insertion_sort(arr3)
if (arr1 == arr2).all() & (arr1 == arr3).all():
continue
else:
print('测试出错')
break
print('测试结束')
#chatgpt版
import random
def random_array(n, v):
return [random.randint(1, v) for _ in range(n)]
def copy_array(arr):
return arr[:]
def same_array(arr1, arr2):
return arr1 == arr2
# 测试
N = 20
V = 100
test_times = 500
print("测试开始")
for i in range(test_times):
n = random.randint(0, N - 1)
arr = random_array(n, V)
arr1 = copy_array(arr)
arr2 = copy_array(arr)
arr3 = copy_array(arr)
selection_sort(arr1)
bubble_sort(arr2)
insertion_sort(arr3)
if not same_array(arr1, arr2) or not same_array(arr1, arr3):
print("出错了!")
# 可以添加更多的调试信息,以便进一步分析问题
print("测试结束")
4、二分搜索
1) 在有序数组中找num
import random
def right(arr, num): #傻瓜式找法,一个一个找
for i in arr:
if i == num:
return True
return False
def exist(arr, num):
if arr is None or len(arr) == 0:
return False
l = 0 #搜索左边界
r = len(arr) - 1 #搜索右边界
while l <= r:
m = (l + r) // 2 #找到位置中位数
if arr[m] == num:
return True
elif arr[m] > num: #如果中位数比num大,则要在左边找,所以右边界r = m-1
r = m - 1
else: #如果中位数比num小,则要在右边找,所以左边界l = m+1
l = m + 1
return False
def random_array(n, v): #随机生成一个取值范围为0~V的规模为n的数组
return [random.randint(1, v) for _ in range(n)]
# 测试
N = 100
V = 1000
test_time = 500
print("测试开始")
for i in range(test_time):
n = random.randint(0, N - 1)
arr = random_array(n, V)
arr.sort() #保证输入的数组是有序的
num = random.randint(1, V) #随机生成num
if right(arr, num) != exist(arr, num):
print("出错了!")
print("测试结束")
2)在有序数组中找>=num的最左位置
#仍用对数器来检验
#暴力解
def right(arr, num):
for i in range(len(arr)):
if num <= arr[i]:
return i
return -1
#二分法
def findleft(arr, num):
ans = -1
l = 0
r = len(arr)-1
while l<=r:
m = l + ((r-l)//2)
if arr[m] < num:
l = m+1
else:
ans = m
r = m-1
return ans
#对数器测试
import random
def random_array(n, v): #随机生成一个取值范围为0~V的规模为n的数组
return [random.randint(0, v) for _ in range(n)]
# 测试
N = 100
V = 1000
test_time = 500
print("测试开始")
for i in range(test_time):
n = random.randint(1, N - 1)
arr = random_array(n, V)
arr.sort() #保证输入的数组是有序的
num = random.randint(1, V) #随机生成num
if right(arr, num) != findleft(arr, num):
print("出错了!")
print("测试结束")
3)寻找峰值
def findPeakPosition(arr):
n = len(arr)
if n == 1:
return 0
if arr[0] > arr[1]:
return 0
if arr[-1] > arr[-2]:
return n-1
#下面进入二分过程
l,r = 1, n-2
while l <= r:
m = l + ((r-l)>>1)
if (arr[m-1] < arr[m]) & (arr[m+1] < arr[m]):
return m
elif arr[m-1] > arr[m]:
r = m-1
else:
l = m+1
p.s. leetcode上竟有时间复杂度更低的解法