目录
- 小矩形覆盖大矩形(斐波那契数列)
- 乘积最大子序列
- 二进制中1的个数
- 反转单向链表
- 判断列表是否为搜索二叉树后续遍历的结果
- 找出列表中出现次数超过列表长度一半的元素
- 找出第n个丑数
- 哪一个小朋友不用表演节目(约瑟夫环)
- 滑动窗口的最大值
- 得到整数列表的中位数
0.1小矩形覆盖大矩形(斐波那契)
# 递归
def rectCover1(number):
if number == 0:
return 0
elif number == 1: # 2*1 1个竖着覆盖
return 1
elif number == 2: # 2*2 2个横着或2个竖着
return 2
else:
return rectCover1(number - 1) + rectCover1(number - 2) # 竖着可以排num-1,横着可以排num-2
print(rectCover(10)) # 89
# 非递归
def rectCover2(number):
if number == 0:
return 0
elif number == 1:
return 1
elif number == 2:
return 2
else:
res = [0, 1, 2] # 结果存入res
while len(res) <= number:
res.append(res[-1] + res[-2])
return res[number]
print(rectCover2(10)) # 89
总结
0.2乘积最大子序列
'''
i:子序列第一个元素在列表中的索引
j:子序列最后一个元素在列表中的索引
mul(i, j) = mul(0, j) / mul(0, i)
mul(0, j) = 0:应该重新开始
mul(0, j) < 0:应该找到mul(0, i)最大的负数
mul(0, j) > 0:应该找到mul(0, i)最小的正数
'''
def numMul(number):
if not number: return
# 目前的累乘
cur_mul = 1
# 前面最小的正数
min_pos = 1
# 前面最大的负数
max_neg = float("-inf")
# 结果
result = float("-inf")
for num in number:
cur_mul *= num
if cur_mul > 0:
result = max(result, cur_mul // min_pos)
min_pos = min(min_pos, cur_mul)
elif cur_mul < 0:
if max_neg != float("-inf"):
result = max(result, cur_mul // max_neg)
else:
result = max(result, num)
max_neg = max(max_neg, cur_mul)
else:
cur_mul = 1
min_pos = 1
max_neg = float("-inf")
result = max(result, num)
return result
num = [1, 2, -2, -2, 5, -4]
print(numMul(num))
40 = -2 * 5 * -4
总结
0.3二进制中1的个数
def oneNumber(n):
print(bin(n)) # 转为二进制
if n < 0:
n = n & 0xffffffff
print(bin(n))
m = len(bin(n)) - 2
count = 0
'''
13 = 1101
(1)保留第一个1其他设为0: 1000 = 8 coun++
(2)保留第二个1其他设为0:0100 = 4 count++
(3)保留第三位0其他设为0:0000 = 0
(4)保留第四位1其他设为0: 0001 = 1 count++
'''
for i in range(0, m):
if n & 2 ** i != 0:
count += 1
return count
print(oneNumber(13)) # 3
print(oneNumber(-1)) # 32(补码为0b11111111111111111111111111111111)
总结
0.4反转单向链表
class LinkedNode:
def __init__(self, x):
self.val = x
self.next = None
def reLinked(head):
if not head or not head.next: # 只有一个节点
return head
pre = None # 前一个节点
cur = head # 当前节点
while cur:
tmp = cur.next # 临时保存下一个节点
cur.next = pre
pre = cur
cur = tmp
return pre
header = LinkedNode(0)
node1 = LinkedNode(1)
header.next = node1
node2 = LinkedNode(2)
node1.next = node2
node3 = LinkedNode(3)
node2.next = node3
def printLinked(head):
p = head
while p:
print(p.val, end=' ')
p = p.next
print()
printLinked(header) # 0 1 2 3
header = reLinked(header)
printLinked(header) # 3 2 1 0
0.5判断列表是否为搜索二叉树后续遍历的结果
'''
二叉搜索树(排序树、查找树)
1.找到根节点
2.遍历序列,找到第一个大于等于根节点的元素 i,i 左侧左子树,右侧右子树
3.判断 i 右侧节点是否都比根节点大,如果有比根节点小的,直接返回 False
4.否则用递归的方式继续处理 i 左侧和右侧的节点
'''
def verify(sequence):
if not sequence:
return False
root = sequence[-1] # 根节点
i = 0
for node in sequence[i:-1]:
if node > root:
break
i += 1
for node in sequence[i:-1]:
if node < root:
return False
left = True
if i > 0:
left = verify(sequence[:-1])
right = True
if i < len(sequence) - 2 and left:
right = verify(sequence[i + 1:])
return left and right
print(verify([1, 4, 7, 6, 3, 13, 14, 10, 8]))
True
总结
0.6找出列表中出现次数超过列表长度一半的元素
def morethanhalf(number):
d = {}
maxNum = 'no'
listCount = len(number)
for n in number:
if d.get(n) is None:
d[n] = 1 # 第一次出现
if maxNum == 'no':
maxNum = n
else:
d[n] += 1
if n != maxNum and d.get(n) > d.get(maxNum):
maxNum = n
if d.get(maxNum) > listCount // 2:
return maxNum
return 'no'
print(morethanhalf([1, 4, 2, 2, 1, 1, 1, 1, 2, 3, 1]))
1
总结
扫描二维码关注公众号,回复:
10187670 查看本文章
0.7找出第n个丑数
6 = 2 * 3 是丑数
14 = 2 * 7 不是丑数
下一个丑数必定是数组中某一个丑数 A * 2、B * 3、C * 5 中最小的值
def getNumber(index):
if index < 1:
return 0
res = [1]
t2 = t3 = t5 = 0
nextindex = 1
while nextindex < index:
minNum = min(res[t2] * 2, res[t3] * 3, res[t5] * 5)
res.append(minNum)
while res[t2] * 2 <= minNum:
t2 +=1
while res[t3] * 3 <= minNum:
t3 += 1
while res[t5] * 5 <= minNum:
t5 += 1
nextindex +=1
return res[nextindex - 1] # 从0开始的
print(getNumber(11))
15
0.8哪一个小朋友不用表演节目(约瑟夫环)
def lastRemain(n, m):
if n < 1 or m < 1:
return -1
temp = 0
for i in range(1, n+1):
temp = (temp + m) % i
return temp
print(lastRemain(10, 12)) # 9
0.9滑动窗口的最大值
def maxInWindows(num, size):
if size <= 0 or len(num) < size:
return []
length = len(num)
result = []
for i in range(0, length - size + 1):
result.append(max(num[i:i+size]))
return result
print(maxInWindows([2, 3, 4, 1, 2, 6, 5, 8, 4], 3))
[4, 4, 4, 6, 6, 8, 8]
0.10得到整数列表的中位数
class Median:
def __init__(self):
self.data = []
def insert(self, num):
self.data.append(num)
self.data.sort()
def getMed(self):
length = len(self.data)
if length % 2 == 1: # 奇数长度
return self.data[length // 2]
else: # 偶数长度
return (self.data[length // 2] + self.data[length // 2 - 1]) / 2.0
median = Median()
median.insert(10)
median.insert(20)
median.insert(5)
print(median.getMed()) # 10
median.insert(12)
print(median.getMed()) # 11.0