寿司代码学习记录(python版)
1 手写快速排序
参考代码:
def quick_sort(arr,start=0,end=None):
if end is None:
end = len(arr) - 1
if end <= start:
return arr
i,j = start,end
ref = arr[start]
while i<j:
if arr[j] >= ref:
j = j - 1
else:
arr[i],arr[i+1],arr[j] = arr[j],arr[i],arr[i+1]
i = i + 1
quick_sort(arr,start=0,end=i-1)
quick_sort(arr,start=i+1,end=end)
return arr
2 二分查找
题目形式:手写一下二分查找算法。给定一个有序数组 arr 和一个目标元素 target ,返回该 target 在 arr 中的索引,若不存在,返回-1。
参考代码:
def binary_search(arr,target):
start,end = 0,len(arr)-1
while True:
if end-start <= 1:
if target == arr[start]:
return start
elif target == arr[end]:
return end
else:
return -1
mid = (start + end)//2
if arr[mid] > target:
end = mid
elif arr[mid] < target:
start = mid
else:
return mid
3 爬楼梯
有一个楼梯,总共有10级台阶,每次只能走一级或者两级台阶,全部走完,有多少种走法?(类似斐波那切数列,可以递归,可以动规)
参考代码:
#动态规划思想
def climb_stairs(n):
if n == 1:
return 1
if n == 2:
return 2
a,b = 1,2
i = 3
while i <= n:
a,b = b,a+b
i += 1
return b
4 两数之和
寻找列表中满足两数之和等于目标值的元素的下标。例如:arr = [2,7,4,9],target = 6 则返回 [0,2],若不存在,返回空列表[]。两数之和问题考察候选人对哈希表可以用空间换取时间这个特性的理解
参考代码:
def sum_of_two(arr,target):
dic = {}
for i,x in enumerate(arr):
j = dic.get(target-x,-1)
if j != -1:
return((j,i))
else:
dic[x] = i
return([])
5 最大回撤
有一个数组,求其中两个数x,y,满足x的索引小于y的索引,使得 x-y 最大。例如 arr = [3,7,2,6,4,1,9,8,5], 最大回撤是6,对应的x=7,y=1。这道题目可能以买卖股票的最佳时机,或者最大抬升等各种形式出现,这也是一道动态规划的史诗级范例。
参考代码:
def max_drawdown(arr):
assert len(arr)>2, "len(arr) should > 2!"
x,y = arr[0:2]
xmax = x
maxdiff = x-y
for i in range(2,len(arr)):
if arr[i-1] > xmax:
xmax = arr[i-1]
if xmax - arr[i] > maxdiff:
maxdiff = xmax - arr[i]
x,y = xmax,arr[i]
print("x=",x,",y=",y)
return(maxdiff)
6 合并两个有序数组
给定两个按升序排列的有序数组,将它们合并成一个新的有序数组。例如:a = [1,2,6,8], b = [2,4,7,10],输出为 arr = [1,2,2,4,6,7,8,10]
参考代码:
def merge_sorted_array(a,b):
c = []
i,j = 0,0
while True:
if len(a) == i:
c.extend(b[:])
return c
elif len(b) == j:
c.extend(a[:])
return c
else:
if a[i] <= b[j]:
c.append(a[i])
i+=1
else:
c.append(b[j])
j+=1
return c
if __name__ =="__main__":
print(merge_sorted_array([1,2,6,8],[2,4,7,10]))
7 最大连续子数组和
给定一个数组,求其最大连续子数组的和。例如:arr = [1,5,-10,2,5,-3,2,6,-3,1]. 输出为:12。对应的连续子数组为 [2,5,-3,2,6]。这道题目也是一道动态规划的祖传范例。
medium
参考代码:
def max_sub_array(arr):
n = len(arr)
maxi,maxall = arr[0],arr[0]
for i in range(1,n):
maxi = max(arr[i],maxi + arr[i])
maxall = max(maxall,maxi)
return(maxall)
print(max_sub_array([1,5,-10,2,5,-3,2,6,-3,1]))
8 最长不重复子串
给定一个字符串,找出没有重复字符的最长的子串。例如输入“abcbefgf”,答案是 “cbefg”。这是一道动态规划+哈希查找的综合应用题。
hard
def longest_substr(s):
dic = {}
start,maxlen,substr = 0,0,""
for i,x in enumerate(s):
if x in dic:
start = max(dic[x]+1,start)
dic[x] = i
else:
dic[x] = i
if i-start+1>maxlen:
maxlen = i-start+1
substr = s[start:i+1]
return(substr)
print(longest_substr("abcbefgf"))
print(longest_substr("abcdef"))
print(longest_substr("abbcddefh"))
9 全排列
给定一个数组,找出其所有可能的排列。例如: arr = [1,1,3],输出为 [[1,1,3],[1,3,1],[3,1,1]]。
这是一道动态规划+排列组合的综合应用题。
medium
参考代码:
import numpy as np
def permutations(arr):
if len(arr)<=1:
return([arr])
t = [arr[0:1]]
i = 1
while i<=len(arr)-1:
a = arr[i]
t = [xs[0:j]+[a]+xs[j:] for xs in t for j in range(i+1)]
t = np.unique(t,axis=0).tolist()
i = i+1
return(t)
print(permutations([1,1,3]))
10 三数之和
题目形式:给定一个数组和目标数target,找出数组中a,b,c满足 a+b+c = target 的所有组合。例如:arr = [-3,-1,-2,1,2,3],target = 0。输出为 [(-3,1,2),(-2,-1,3)]
hard
参考代码:
def sum_of_three(arr,target):
assert len(arr)>=3,"len(arr) should >=3!"
arr.sort()
ans = set()
for k,c in enumerate(arr):
i,j = k+1,len(arr)-1
while i<j:
if arr[i]+arr[j]+c <target:
i = i+1
elif arr[i]+arr[j]+c > target:
j = j-1
else:
ans.update({(arr[k],arr[i],arr[j])})
i = i+1
j = j-1
return(list(ans))
print(sum_of_three([-3,-1,-2,1,2,3],0))