# fibonacci
def fib(n):
a, b = 0, 1
print(1)
for i in range(n - 1):
a, b = b, b + a
print(b) # 打印第5个数
# 跳台阶
def jump_recur(n):
if n == 1 or n == 0:
return 1
return jump_recur(n - 1) + jump_recur(n - 2)
def jump_dp(n): # 动态规划思想: 1到2 1中跳法,2到3 是一种跳法
if n == 1:
return 1
if n == 2:
return 2
a, b, c = 1, 2, 0
while n > 2:
c = a + b
a, b = b, c
n -= 1
return c
# 二进制中1的个数
'''输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。'''
'''负数的补码:正数二进制取反,首位+1 。默认八位数'''
def num_1(num):
if num == 0:
return 0
if num > 0:
binary = str(bin(num)[2:])
a = binary.count('0')
b = (8 - len(binary))
return a + b
if num < 0:
binary = str(bin(num)[3:])
a = binary.count('0')
b = (8 - len(binary))
return a + b + 1
# 调整数组中奇偶数位置,奇前偶后
def adjust(lst):
while True:
flag = 0
for i in range(len(lst)):
if i > 0:
a, b = lst[i], lst[i - 1]
if a % 2 != 0 and b % 2 == 0: # 如果是奇数且前面是偶数
lst[i], lst[i - 1] = b, a
flag += 1
if flag == 0:
break
return lst
# 输入链表,输出倒数第K个节点: 压栈再弹出就行了
class Node:
def __init__(self, val):
self.val = val
self.next = None
class Llst:
def __init__(self):
self.head = None
self.end = None
def append(self, val):
if not self.head:
self.head = self.end = Node(val)
else:
self.end.next = Node(val)
self.end = self.end.next
#顺时针打印矩阵的外圈
def prt_one(s, n, lst):
for i in range(s, n + 1):
print(lst[s][i])
for i in range(s + 1, n + 1):
print(lst[i][n])
for i in range(n - 1, s - 1, -1):
print(lst[n][i])
for i in range(n - 1, s, -1):
print(lst[i][s])
# 顺时针打印矩阵
def rect(array):
l = len(array) // 2
l2 = []
for i in range(l):
if i == len(array) - i:
break
l2.append((i, len(array) - 1 - i))
for i in l2:
prt_one(i[0], i[1], array)
if len(array) % 2 != 0: # 长度为奇数补打最中间那个数
print(array[len(array) // 2 + 1])
# l = [[x for x in range(i, i + 4)] for i in range(1, 17, 4)] # 生成4*4矩阵
# rect(l) 执行
# 全排列使用的函数
def ins(tar, t):
tar = list(tar) # a,b,c,d
l = []
for i in range(len(tar)):
tar.insert(i, t)
s = ''.join(tar)
l.append(s)
tar.remove(t)
if i == len(tar) - 1:
tar.append(t)
l.append(''.join(tar))
return l
# 字符串全排列问题:1、递归实现 2、 回溯法排列树思想解决3、动态规划实现
def perm_dp(alpha): # 动态规划实现
l = [] # 上一个list
new_l = [] # 新list
for i in alpha: # 有几个字母运行几次
tar = i # 分别用 a,b,c,d进行排列
if not l:
l.append(tar)
else:
for j in l:
new_l += ins(j, tar)
l = new_l[:]
new_l = []
print(l)
perm_dp('abc')
def perm(l):
if (len(l) <= 1):
return [l]
r = []
for i in range(len(l)):
s = l[:i] + l[i + 1:]
p = perm(s)
for x in p:
r.append(l[i:i + 1] + x)
return r
# 找出出现次数超过一半的数字
def find_num(array):
d = {}
num = len(array)
for i in array:
d[i] = d.get(i, 0) + 1
if d[i] >= len(array) / 2:
print('the num is {}'.format(i))
return i
print('no such number')
# 返回最大连续子序列的和,包含负数
def ret_maxsum(array):
sum = 0
l = []
for i in range(len(array)):
sum += array[i]
if sum > 0:
l.append(sum)
else:
sum = 0
return max(l)
# 1 到 n 中 ,1 出现的次数:1、穷举(可进一步优化) 2、分类讨论
def find_1(n):
num_1 = 0
for i in range(1, n + 1):
num_1 += str(i).count('1')
print('time 1 appears {}'.format(num_1))
return num_1
# 输入正整数数组,拼成一个最小的数字:1、由于位数不变,首数字最小的依次排前即可
def make_min(array):
l2 = sorted(array, key=lambda x: int(str(x)[0]))
return int(''.join(l2))
# 丑数, 只包含2,3,5质因子的数称为丑数,从小到大输出第N个丑数:依次循环÷2,3,5假如最终能等于1则
def find_ugly(n):
lst = [1, 2, 3, 5] # initial list
if n > 6: # 从6开始
for i in range(6, n + 1):
a = i
for j in [2, 3, 5]: # 判断丑数部分
while True:
if a == 1 and j == 5:
lst.append(i)
break
if a == 1:
break
if a % j == 0:
a = a // j
else:
break
return lst
# 第一个只出现一次的字符,字符长度1w以内
def find_one(string):
d = {}
for i in range(len(string)):
tar = string[i]
if not d.get(tar, False): # 如果不在字典里就添加
d[tar] = i + 1 # 用来记录位置
else: # 已存在 就把值标记成True,
d[tar] = True
lst = list(d.items())
lst = sorted(lst, key=lambda x: x[1] if x[1] != True else 10001)
print(lst)
return lst[0][1] - 1 if lst[0][1] != True else -1
# 统计一个数字在排序数组中出现的次数:先二分查找找到这个数,然后whileTrue遍历 前后元素,直到不同
def func():
# 不难就先不写了
# 注意元素正好在首尾要做条件判断,规避索引越界
pass
# 整形数组除了两个数字外,别的都出现偶数次,找出这两个只出现一次的数字
def solu():
# 第一种方法:快排排序,for循环遍历找到只出现一次的
# 第二种,用异或性质:偶数个相同的数进行异或,结果是0,奇数个数异或结果是自身
# 不会写,日后再说
pass
# 输出所有和为S 的连续正整数序列,比如1819202122 加起来是100
def out_S(n):
# 根据等差数列中值性质来做,不难,耗时,先放着
pass
# 和为S的两个数字 : 输入递增排序的数组[1,2,4,5,7,8]和一个数字S,在数组中查找两个数使得和正好等于S,多对则输出乘机最小的
def sum_s(array, S):
# 类似二分思想,先找最中间两个数,和大就 往下遍历 ,和小就往上遍历
mid = (len(array)-1)//2
s,b = mid ,mid+1
l = []
while True:
if sum([array[s],array[b]]) > S:
s-=1
if s<0:
print('small {}={}'.format(s,b))
return l
else:
continue
if sum([array[s],array[b]]) < S:
b +=1
if b>= len(array):
print('beyong {}={}'.format(s,b))
return l
else:
continue
if sum([array[s],array[b]]) == S:
l.append((array[s],array[b]))
s-=1;b+=1
if s<0 or b>=len(array):
print('结束{}={}'.format(s,b))
return l
else:
continue
# 循环左移k位,比如abcde 变成 cdeab
def cyc_left_move(string, k):
k = k % len(string) # 先处理k 比string长度大的情况 比如abcd 左移9次相当于左移1次
return ''.join([string[k:], string[:k]])
# 翻转单词顺序: student a am I
def rever(string):
return ' '.join(reversed(string.split(' ')))
# 一个数组里有未知的重复数字,找出第一个重复的数字,数组长度为n ,里面数字范围0 到 n-1
def findfirst(array):
d = {}
for i in array:
if not d.get(i, 0):
d[i] = d.get(i, 0) + 1
else:
return i
'''给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。
例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,
他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个:
{[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1},
{2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。'''
def max_window(array, size): # 假设size不超过
lst = []
for i in range(len(array) - size + 1):
win = array[i:i + size]
lst.append(max(win))
return lst
# 给定一个字母矩阵,查找是否有一条路径 满足一个单词
# 比如[[a,b,c,e],[s,f,c,s],[a,d,e,e]] 包含bcced 这个单词,走过的路劲不能重复
a = [['a', 'b', 'c', 'e'], ['s', 'f', 'c', 's'], ['a', 'd', 'e', 'e']]
def str_path(array, word):#可以用回溯法,也可以所有路径都存储下来一个个判断
l = [] # 用于存放所有可行路径
X = len(array) - 1
Y = len(array[0]) - 1
for i in range(X): # 找到所有首字母的位置
for j in range(Y):
if array[i][j] == word[0]:
l.append([(i, j)])
for alp in range(1, len(word)): # 遍历路径字母
alpha = word[alp]
new_path = []
for loca in l: # 对于每条路径的尾部 loca = [(x,y),(x2,y2)]
print('============================')
x, y = loca[-1][0], loca[-1][1] # 尾部位置
up, down, left, right = (x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1) # 下一位置
for i in (up, down, left, right): # 对于每个合法位置都新建一条路径
if 0 <= i[0] <= X and 0 <= i[1] <= Y: # 检验合法的位置
print(i)
if array[i[0]][i[1]] == alpha and (i not in loca): # 如果位置合法且为目标字母则加入路径,走过的路径不加入
new_path.append(loca + [i])
l = new_path[:] # 更新路径
print(l)
return l