1.斐波那契数列
要求输入一个整书n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
class Solution:
def Fibonacci(self, n):
# write code here
res = [0,1]
while(len(res)<=n):
res.append(res[-1]+res[-2])
return res[n]
2.用两个栈实现队列
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.stack1 = []
self.stack2 = []
def push(self, node):
# write code here
self.stack1.append(node)
def pop(self):
# return xx
if not len(self.stack2) == 0:
return self.stack2.pop()
else:
while len(self.stack1) > 0:
self.stack2.append(self.stack1.pop())
return self.stack2.pop()
3.串的模式匹配算法
'''
在主串s的pos后寻找子串t并返回索引,时间复杂度O[(n-m+1)*m]
'''
def Index(s, t, pos):
i = pos
j = 0
while i<len(s) and j<len(t):
if s[i]==t[j]:
i += 1
j += 1
else:
i = i-j+1
j = 0
if j == len(t):
return i-j
else:
return False
4.重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre, tin):
# write code here
if not pre or not tin:
return None
root = TreeNode(pre.pop(0))
index = tin.index(root.val)
root.left = self.reConstructBinaryTree(pre,tin[:index])
root.right = self.reConstructBinaryTree(pre,tin[index+1:])
return root
5.二叉树的生成(python)
class Node(object):
def __init__(self, number):
self.val = number
self.lchild = None
self.rchild = None
class Tree(object):
lis = [] ##用来保存没有左右孩子的节点,
def __init__(self):
self.root = None
def add(self, number):
node = Node(number)
if self.root == None:
self.root = node
Tree.lis.append(self.root)
else:
while True:
point = Tree.lis[0]
if point.lchild==None:
point.lchild = node
Tree.lis.append(point.lchild)
return
elif point.rchild==None:
point.rchild = node
Tree.lis.append(point.rchild)
Tree.lis.pop(0) ###如果该节点的左右孩子都有则pop
return
def traverse(self): ##层次遍历
if self.root == None:
return None
q = [self.root]
res = [self.root.val]
while q!=[]:
pop_node = q.pop(0)
if pop_node.lchild is not None:
q.append(pop_node.lchild)
res.append(pop_node.lchild.val)
if pop_node.rchild is not None:
q.append(pop_node.rchild)
res.append(pop_node.rchild.val)
return res
def preorder(self, root): ###前序遍历
if root == None:
return []
res = [root.val]
left_val = self.preorder(root.lchild)
right_val = self.preorder(root.rchild)
return res+left_val+right_val
def preorder1(self, root): ##前序遍历迭代
if root == None:
return []
p = root
res = []
stack = []
while p or stack:
if p:
res.append(p.val)
stack.append(p)
p = p.lchild
else:
temp = stack.pop()
p = temp.rchild
return res
def inorder(self, root): ###中序遍历
if root == None:
return []
res = [root.val]
left_val = self.inorder(root.lchild)
right_val = self.inorder(root.rchild)
return left_val+res+right_val
def inorder2(self, root):
if root == None:
return []
p = root
stack = []
res = []
while p or stack:
if p:
stack.append(p)
p = p.lchild
else:
temp = stack.pop()
res.append(temp.val)
p=temp.rchild
return res
def postorder(self, root):
if root == None:
return []
res = [root.val]
left_val = self.postorder(root.lchild)
right_val = self.postorder(root.rchild)
return left_val+right_val+res
def postorder1(self, root):
if root == None:
return []
p = root
stack = []
res = []
while p or stack:
if p:
res.append(p.val)
stack.append(p)
p = p.rchild
else:
temp = stack.pop()
p = temp.lchild
return res[::-1]
t = Tree()
for i in range(10):
t.add(i)
print('层序遍历:',t.traverse())
print('前序遍历:',t.preorder(t.root))
print('前序遍历:',t.preorder1(t.root))
print('中序遍历:',t.inorder(t.root))
print('中序遍历:',t.inorder2(t.root))
print('后序遍历:',t.postorder(t.root))
print('后序遍历:',t.postorder1(t.root))
6.跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
对于本题,前提只有 一次 1阶或者2阶的跳法。
a.如果两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法是f(n-1);
b.假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2)
c.由a\b假设可以得出总跳法为: f(n) = f(n-1) + f(n-2)
d.然后通过实际的情况可以得出:只有一阶的时候 f(1) = 1 ,只有两阶的时候可以有 f(2) = 2
e.可以发现最终得出的是一个斐波那契数列:
| 1, (n=1)
f(n) = | 2, (n=2)
| f(n-1)+f(n-2) ,(n>2,n为整数)
def jumpFloor(number):
###递归解法,空间复杂度太大,在牛客网上提交将显示,运行超时:您的程序未能在规定时间内运行结束,请检查是否循环有错或算法复杂度过大。因此采用斐波那契迭代方法。
# write code here
if number <= 0:
return -1
if number == 1:
return 1
elif number == 2:
return 2
else:
return jumpFloor(number-1)+jumpFloor(number-2)
def jumpfloor(number):
###迭代解法
f1 = 1
f2 = 2
if number <= 0:
return -1
elif number == 1 or number == 2:
return number
else:
n = 2
while(n<number):
f2 += f1
f1 = f2 - f1
n += 1
return f2
6.变态跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
链接:https://www.nowcoder.com/questionTerminal/22243d016f6b47f2a6928b4313c85387
来源:牛客网
f(1) = 1
f(2) = f(2-1) + f(2-2) //f(2-2) 表示2阶一次跳2阶的次数。
f(3) = f(3-1) + f(3-2) + f(3-3)
...
f(n) = f(n-1) + f(n-2) + f(n-3) + ... + f(n-(n-1)) + f(n-n)
说明:
1)这里的f(n) 代表的是n个台阶有一次1,2,...n阶的 跳法数。
2)n = 1时,只有1种跳法,f(1) = 1
3) n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1) ,f(2) = f(2-1) + f(2-2)
4) n = 3时,会有三种跳得方式,1阶、2阶、3阶,
那么就是第一次跳出1阶后面剩下:f(3-1);第一次跳出2阶,剩下f(3-2);第一次3阶,那么剩下f(3-3)
因此结论是f(3) = f(3-1)+f(3-2)+f(3-3)
5) n = n时,会有n中跳的方式,1阶、2阶...n阶,得出结论:
f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + ... + f(n-1)
6) 由以上已经是一种结论,但是为了简单,我们可以继续简化:
f(n-1) = f(0) + f(1)+f(2)+f(3) + ... + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2)
f(n) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2) + f(n-1) = f(n-1) + f(n-1)
可以得出:
f(n) = 2*f(n-1)
7) 得出最终结论,在n阶台阶,一次有1、2、...n阶的跳的方式时,总得跳法为:
| 1 ,(n=0 )
f(n) = | 1 ,(n=1 )
| 2*f(n-1),(n>=2)
# -*- coding:utf-8 -*-
class Solution:
def jumpFloorII(self, number):
# write code here
return 2**(number-1)
7.二进制中一的个数
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
def NumberOf1(self, n):
# write code here
count = 0
if n<0:
n = n & 0xffffffff ###n为负数时得到它的补码,因为python中负数的二进制表示是原码前面加-
while n:
count += 1
n = (n - 1) & n
return count
链接:https://www.nowcoder.com/questionTerminal/8ee967e43c2c4ec193b040ea7fbb10b8?f=discussion
来源:牛客网
分析一下代码: 这段小小的代码,很是巧妙。
如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减1,那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1(如果最右边的1后面还有0的话)。其余所有位将不会受到影响。
举个例子:一个二进制数1100,从右边数起第三位是处于最右边的一个1。减去1后,第三位变成0,它后面的两位0变成了1,而前面的1保持不变,因此得到的结果是1011.我们发现减1的结果是把最右边的一个1开始的所有位都取反了。这个时候如果我们再把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。如1100&1011=1000.也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数的二进制有多少个1,就可以进行多少次这样的操作。
需要注意python中负数的二进制表示是原码前面加负号(比如bin(100)就是-0b1100100),和c/java直接就是补码不同,因此需要将负号表示转换为补码,对于负数,最高位为1,而负数在计算机是以补码存在的,往右移,符号位不变,符号位1往右移,最终可能会出现全1的情况,导致死循环。与0xffffffff相与,就可以消除负数的影响,得到负数的补码表示
8.数值的整数次方
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
# -*- coding:utf-8 -*-
class Solution:
def Power(self, base, exponent):
# write code here
'''
一般解法考虑base是否为0,以及exponent是否为0
'''
current = base
if base == 0 and exponent>0:
return 0
elif base == 0 and exponent<=0:
raise ZeroDivisionError()
else:
if exponent == 0:
return 1
elif exponent >= 0:
while(exponent-1):
current *= base
exponent -= 1
return current
else:
exponent = -exponent
while(exponent-1):
current *= base
exponent -= 1
return 1/current
#return base**exponent ###一行解法
'''
快速求幂算法 参考https://blog.csdn.net/hkdgjqr/article/details/5381028
'''
def fast_power(self, base, exponent):
if base == 0:
return 0
if exponent == 0:
return 1
e = abs(exponent)
tmp = base
res = 1
while(e > 0):
#如果最后一位为1,那么给res乘上这一位的结果
if (e & 1 == 1):
res =res * tmp
e = e >> 1
tmp = tmp * tmp
return res if exponent > 0 else 1/res
9.链表中倒数第k个结点
输入一个链表,输出该链表中倒数第k个结点。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindKthToTail(self, head, k):
# write code here
if head == None or k<=0:
return None
p1 = head
p2 = head
while(k > 1):
if p2.next == None:
return None
else:
p2 = p2.next
k -= 1
while(p2.next != None):
p1 = p1.next
p2 = p2.next
return p1
设置两个指针,p1,p2,先让p2走k-1步,然后再一起走,直到p2为最后一个 时,p1即为倒数第k个节点
10.反转链表
输入一个链表,反转链表后,输出新链表的表头。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
# write code here
if pHead == None or pHead.next == None:
return pHead
else:
pre = None
cur = pHead
while(cur):
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
return pre
11.合并两个排序的链表
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
'''
非递归方法
'''
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回合并后列表
def Merge(self, pHead1, pHead2):
# write code here
if pHead1 == None:
return pHead2
elif pHead2 == None:
return pHead1
else:
MergedHead = current = None
while pHead1 and pHead2:
if pHead1.val <= pHead2.val:
if MergedHead == None:
MergedHead = current = pHead1
else:
current.next = pHead1
current = current.next
pHead1 = pHead1.next
else:
if MergedHead == None:
MergedHead = current = pHead2
else:
current.next = pHead2
current = current.next
pHead2 = pHead2.next
if pHead1 == None:
current.next = pHead2
elif pHead2 == None:
current.next = pHead1
return MergedHead
'''
递归方法
'''
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回合并后列表
def Merge(self, pHead1, pHead2):
# write code here
if pHead1 == None:
return pHead2
elif pHead2 == None:
return pHead1
if pHead1.val <= pHead2.val:
MergedHead = pHead1
MergedHead.next = self.Merge(pHead1.next, pHead2)
else:
MergedHead = pHead2
MergedHead.next = self.Merge(pHead1, pHead2.next)
return MergedHead
12.树的子结构
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def HasSubtree(self, pRoot1, pRoot2):
# write code here
result = False
if pRoot1 != None and pRoot2 != None:
if pRoot1.val == pRoot2.val:
result = self.DoesTree1hasTree2(pRoot1, pRoot2)
if not result:
result = self.HasSubtree(pRoot1.left, pRoot2)
if not result:
result = self.HasSubtree(pRoot1.right, pRoot2)
return result
def DoesTree1hasTree2(self, pRoot1, pRoot2):
if pRoot2 == None:
return True
if pRoot1 == None:
return False
if pRoot1.val != pRoot2.val:
return False
return self.DoesTree1hasTree2(pRoot1.left, pRoot2.left) and self.DoesTree1hasTree2(pRoot1.right, pRoot2.right)
1、首先设置标志位result = false,因为一旦匹配成功result就设为true,
剩下的代码不会执行,如果匹配不成功,默认返回false
2、递归思想,如果根节点相同则递归调用DoesTree1HaveTree2(),
如果根节点不相同,则判断tree1的左子树和tree2是否相同,
再判断右子树和tree2是否相同
3、注意null的条件,HasSubTree中,如果两棵树都不为空才进行判断,
DoesTree1HasTree2中,如果Tree2为空,则说明第二棵树遍历完了,即匹配成功,
tree1为空有两种情况(1)如果tree1为空&&tree2不为空说明不匹配,
(2)如果tree1为空,tree2为空,说明匹配。
13.二叉树的镜像
二叉树的镜像定义:
源二叉树
8
/ \
6 10
/ \ / \
5 7 9 11
镜像二叉树
8
/ \
10 6
/ \ / \
11 9 7 5
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回镜像树的根节点
def Mirror(self, root):
# write code here
if root == None:
return root
tmp = root.left
root.left = root.right
root.right = tmp
self.Mirror(root.left)
self.Mirror(root.right)
return root
14.顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
'''
解法一
'''
# -*- coding:utf-8 -*-
class Solution:
# matrix类型为二维列表,需要返回列表
def printMatrix(self, matrix):
# write code here
if matrix == None:
return []
res = []
while matrix:
res += matrix.pop(0)
if matrix and matrix[0]:
for row in matrix:
res.append(row.pop())
if matrix:
res += matrix.pop()[::-1]
if matrix and matrix[0]:
for row in matrix[::-1]:
res.append(row.pop(0))
return res
'''
解法二:
可以模拟魔方逆时针旋转的方法,一直做取出第一行的操作
例如
1 2 3
4 5 6
7 8 9
输出并删除第一行后,再进行一次逆时针旋转,就变成:
6 9
5 8
4 7
继续重复上述操作即可。
'''
链接:https://www.nowcoder.com/questionTerminal/9b4c81a02cd34f76be2659fa0d54342a?f=discussion
来源:牛客网
class Solution:
# matrix类型为二维列表,需要返回列表
def printMatrix(self, matrix):
# write code here
result = []
while(matrix):
result+=matrix.pop(0)
if not matrix or not matrix[0]:
break
matrix = self.turn(matrix)
return result
def turn(self,matrix):
num_r = len(matrix)
num_c = len(matrix[0])
newmat = []
for i in range(num_c):
newmat2 = []
for j in range(num_r):
newmat2.append(matrix[j][i])
newmat.append(newmat2)
newmat.reverse()
return newmat
'''
解法三
'''
# -*- coding:utf-8 -*-
class Solution:
# matrix类型为二维列表,需要返回列表
def printMatrix(self, matrix):
# write code here
if matrix == None:
return None
width = len(matrix)
hight = len(matrix[0])
res = []
if width == 1:
for i in range(hight):
res.append(matrix[0][i])
return res
elif hight == 1:
for i in range(width):
res.append(matrix[i][0])
return res
elif width == 2:
res += matrix[0]
for i in range(hight-1,-1,-1):
res.append(matrix[1][i])
elif hight == 2:
res += matrix[0]
for i in range(1,width):
res.append(matrix[i][1])
for i in range(width-1,0,-1):
res.append(matrix[i][0])
else:
res += matrix[0]
for i in range(1,width):
res.append(matrix[i][-1])
for i in range(hight-2,-1,-1):
res.append(matrix[-1][i])
for i in range(width-2,0,-1):
res.append(matrix[i][0])
if width > 2 and hight > 2:
matrixleft = []
for i in range(1,width-1):
matrixleft.append(matrix[i][1:-1])
resleft = self.printMatrix(matrixleft)
res += resleft
return res
15.字符串最长回文子串(LeetCode5)
给定一个字符串 s
,找到 s
中最长的回文子串。你可以假设 s
的最大长度为 1000。
解法一:暴力搜索(Leetcode通过101/103)
class Solution:
def longestPalindrome(self, s: str) -> str:
n = length = len(s)
if length == 0:
return s
while(length>0):
for i in range(n-length+1):
subs = s[i:i+length]
if self.isPalindrome(subs):
return subs
length -= 1
def isPalindrome(self, string):
n = len(string)
length = n//2 if n%2 == 0 else n//2+1
for i in range(length):
if string[i] != string[-i-1]:
return False
return True
方法二:动态规划
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
if n < 2:
return s
dp = [[0 for i in range(n)] for i in range(n)]
longest_slen = 1
res = s[0]
for j in range(1,n):
for i in range(j):
if s[i] == s[j] and (j-i <=2 or dp[i+1][j-1]):
dp[i][j] = 1
cur_len = j-i+1
if cur_len > longest_slen:
longest_slen = cur_len
res = s[i:j+1]
return res
16.字符串的字典序排列
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
参考:
https://blog.csdn.net/weixin_42018258/article/details/80683826
https://www.cnblogs.com/pmars/archive/2013/12/04/3458289.html
思路一:递归
# -*- coding:utf-8 -*-
class Solution:
def Permutation(self, ss):
# write code here
if len(ss)<2:
return ss.split()
strs = list(ss)
res = []
self.PermutationHelper(strs, 0, len(strs), res)
return sorted(res)
def PermutationHelper(self, strs, begin, end, res):
if begin == end-1:
res.append(''.join(strs))
for i in range(begin, end):
if i != begin and strs[i]==strs[begin]:
continue
self.swap(strs, begin, i)
self.PermutationHelper(strs, begin+1, end, res)
self.swap(strs, begin, i)
def swap(self,strs, a, b):
tmp = strs[a]
strs[a] = strs[b]
strs[b] = tmp
思路二:非递归
【例】 如何得到346987521的下一个
1,从尾部往前找第一个P(i-1) < P(i)的位置
3 4 6 <- 9 <- 8 <- 7 <- 5 <- 2 <- 1
最终找到6是第一个变小的数字,记录下6的位置i-1
2,从i位置往后找到最后一个大于6的数
3 4 6 -> 9 -> 8 -> 7 5 2 1
最终找到7的位置,记录位置为m
3,交换位置i-1和m的值
3 4 7 9 8 6 5 2 1
4,倒序i位置后的所有数据
3 4 7 1 2 5 6 8 9
则347125689为346987521的下一个排列
所以思路就是先排序得到字典序最小的,然后不断的找下一个字典序排列。
# -*- coding:utf-8 -*-
class Solution:
def Permutation(self, ss):
# write code here
if len(ss) < 2:
return ss.split()
ss = sorted(ss)
res = []
next_pmt = ss
while next_pmt != []:
res.append(''.join(next_pmt))
next_pmt = self.get_next_pmt(next_pmt)
return res
def get_next_pmt(self, ss):
i = len(ss)-2
while (i>=0 and ss[i] >= ss[i+1]):
i -= 1
if i < 0:
return []
j = len(ss)-1
while ss[j]<=ss[i]:
j -= 1
self.swap(ss, i, j)
self.reverse(ss, i+1, len(ss)-1)
return ss
def swap(self, ss, i, j):
temp = ss[i]
ss[i] = ss[j]
ss[j] = temp
def reverse(self, ss, i ,j):
while i<j:
self.swap(ss, i, j)
i += 1
j -= 1
17.连续子数组的最大和
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
# -*- coding:utf-8 -*-
'''动态规划'''
class Solution:
def FindGreatestSumOfSubArray(self, array):
# write code here
if array is None:
return 0
dp = [0 for _ in range(len(array))]
dp [0] = array[0]
max_sum= dp[0]
for i in range(1, len(array)):
if dp[i-1] > 0:
dp[i] = dp[i-1] + array[i]
else:
dp[i] = array[i]
if dp[i] > max_sum:
max_sum = dp[i]
return max_sum
进阶:最大子矩阵
链接:https://www.nowcoder.com/questionTerminal/a5a0b05f0505406ca837a3a76a5419b3
来源:牛客网
已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵。 比如,如下4 * 4的矩阵 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 的最大子矩阵是 9 2 -4 1 -1 8 这个子矩阵的大小是15。
思路:
//要求一个二维矩阵的最大子矩阵,首先要会求一维矩阵的最大子矩阵(即一维数组连续最大和)
//假设原二维矩阵的最大子矩阵所在的行为i到j
// 1 当i = j时,则最大子矩阵为第i行的连续最大和
// 2 当i != j时,现在我们已经直到最大子矩阵的行,要求的是其所在的列
// 我们把从第i行到第j行的所有行相加,得到一个只有一行的一维数组,则该一维数组
// 的连续最大和就是最大子矩阵。
//求一维数组的连续最大和
//动态规划问题,设DP[i]=以v[i]元素结尾的连续最大和
//则DP[i] = max(DP[i-1] + v[i], v[i])
//初始条件为DP[0] = v[0]
import sys
if __name__ == '__main__':
n = int(input().strip())
matrix = []
for i in range(n):
matrix.append(list(map(int, input().strip().split())))
def func(array):
dp = [0 for _ in range(len(array))]
dp[0] = array[0]
max_n = dp[0]
for i in range(1, len(array)):
if dp[i-1] > 0:
dp[i] = dp[i-1] + array[i]
else:
dp[i] = array[i]
if max_n < dp[i]:
max_n = dp[i]
return max_n
max_sum = 0
for i in range(n):
array = [0]*n
for j in range(i, n):
for k in range(n):
array[k] += matrix[j][k]
ms = func(array)
if max_sum < ms:
max_sum = ms
print(max_sum)
18.把数组排成最小的数
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
思路:排序,排序的规则是比较两个字符串前后合并之后数字的大小对比,见cmp函数
# -*- coding:utf-8 -*-
class Solution:
def PrintMinNumber(self, numbers):
# write code here
if len(numbers) == 0:
return ''
def cmp(a,b):
if int(a+b)>int(b+a):
return True
else:
return False
numbers = list(map(str, numbers))
flag = True
for i in range(len(numbers)):
if flag == False:
break
flag = False
for j in range(len(numbers)-2, i-1, -1):
if cmp(numbers[j], numbers[j+1]):
numbers[j], numbers[j+1] = numbers[j+1], numbers[j]
flag = True
return int(''.join(numbers))
19.丑数
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
# -*- coding:utf-8 -*-
class Solution:
def GetUglyNumber_Solution(self, index):
# write code here
if index < 7:
return index
res = [1]
t1 = t2 = t3 = 0
for i in range(1, index):
res.append(min(res[t1]*2, res[t2]*3, res[t3]*5))
if res[i] == res[t1]*2:
t1 += 1
if res[i] == res[t2]*3:
t2 += 1
if res[i] == res[t3]*5:
t3 += 1
return res[-1]