剑指offer | 第二章
03-数组中重复的数字
# -*- coding: utf-8 -*-
# 面试题3:数组中重复的数据
# 题目一:找出数组中重复的数字
# 在一个长度为n的数组里的所有数字都在0到n-1的范围内。
# 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。
# 请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},
# 那么对应的输出是第一个重复的数字2。
# 方法一:对输入数组排序,从投到尾扫描,即可得到重复的元素,时间复杂度O(nlogn)
# 方法二:利用集合,检测元素是否重复
# 方法三:以将对应元素放到对应位置的方式重排数组,然后发现重复元素
# 以牛客网写法为主
class Solution:
# 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
# 函数返回True/False
# 方法一
def duplicate1(self, numbers, duplication):
# write code here
if numbers == None or len(numbers) <= 1:
return False
for i in range(len(numbers)):
if numbers[i] < 0 or numbers[i] > len(numbers) - 1:
return False
numbers.sort()
for i in range(len(numbers) - 1):
if numbers[i] == numbers[i + 1]:
duplication[0] = numbers[i] #
print(duplication[0])
return True
return False
# 方法二
def duplicate2(self, numbers, duplication):
if numbers == None or len(numbers) <= 1:
return False
usedDic = set()
for i in range(len(numbers)):
if numbers[i] < 0 or numbers[i] > len(numbers) - 1:
return False
if numbers[i] not in usedDic:
usedDic.add(numbers[i])
else:
duplication[0] = numbers[i]
print(duplication[0])
return True
return False
# 方法三
def duplicate3(self, numbers, duplication):
if numbers == None or len(numbers) <= 1:
return False
for i in range(len(numbers)):
if numbers[i] < 0 or numbers[i] > len(numbers) - 1:
return False
for i in range(len(numbers)):
while (numbers[i] != i):
if numbers[i] == numbers[numbers[i]]: # 如果第i个数所对应的数等于i
duplication[0] = numbers[i]
print(duplication[0])
return True
else:
temp = numbers[i]
numbers[i] = numbers[temp] # numbers[temp]这里对应的是书中的第m个数字
numbers[temp] = temp
return False
if __name__ == "__main__":
print("03_01")
Array = [2, 3, 1, 0, 2, 5, 3]
Dup = [0] # Dup先定义为一个长度为1的数组,用来存储第一个重复的数字
print("方法1--------------------")
print(Solution().duplicate1(Array, Dup))
print("方法2--------------------")
print(Solution().duplicate2(Array, Dup))
print("方法3--------------------")
print(Solution().duplicate3(Array, Dup))
04-二维数组中的查找
# -*- coding: utf-8 -*-
"""
面试题4:二维数组中的查找
题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
"""
class Solution:
def Find(self, target, array):
'简单粗暴,二层遍历,时间不是最优'
found = False
rows, columns = len(array),len(array[0])
if array and rows > 0 and columns > 0:
for row in range(rows):
for column in range(columns):
if array[row][column] == target:
found = True
return found
def Find2(self, target, array):
'从右上角开始判断'
found = False
rows = len(array)
columns = len(array[0])
if array and rows > 0 and columns > 0:
row = 0
column = columns - 1
while row < rows and column >= 0:
if array[row][column] == target:
found = True
break
elif array[row][column] > target:
column -= 1
else:
row += 1
return found
def Find3(self, target, array):
'从左下角开始判断'
found = False
rows = len(array)
columns = len(array[0])
if array and rows > 0 and columns > 0:
row = rows -1
column = 0
while row >= 0 and column < columns:
if array[row][column] == target:
found = True
break
elif array[row][column] > target:
row -= 1
else:
column += 1
return found
if __name__ == "__main__":
Array = [[1, 2, 8, 9],
[2, 4, 9, 12],
[4, 7, 10, 13],
[6, 8, 11, 15]]
Target = 7
print(Solution().Find(Target, Array))
print(Solution().Find2(Target, Array))
print(Solution().Find3(Target, Array))
05-替换空格
# -*- coding: utf-8 -*-
"""
面试题5:替换空格
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy,
则经过替换之后的字符串为We%20Are%20Happy。
"""
class Solution:
# s 源字符串
def replaceSpace1(self, s):
'使用join'
if s == "" or len(s) <= 0:
return ""
return "%20".join(s.split(" "))
def replaceSpace2(self, s):
'使用replace方法'
if s == "" or len(s) <= 0:
return ""
return s.replace(" ", "%20")
def replaceSpace3(self, s):
"""
剑指offer解法:
①先计算源字符串数组长度,并统计空格数量
②新字符串数组长度=源数组长度+2*空格数量
③在新字符串数组上,从后向前遍历,通过两个index移动并复制
:param s: 输入字符串s
:return: 替换后的字符串
"""
if s == "" or len(s) <= 0:
return ""
# 计算空格数量
s = list(s)
count = 0
for i in s:
if i == " ":
count += 1
p1 = len(s) - 1 # p1初始化为原始字符串数组末尾的index
s += [None] * (count * 2) # 将s扩充为新长度
p2 = len(s) - 1 # p2初始化为新字符串数组末尾的index
while p1 >= 0:
if s[p1] == ' ':
for i in ['0', '2', '%']:
s[p2] = i
p2 -= 1
else:
s[p2] = s[p1]
p2 -= 1
p1 -= 1
return ''.join(s)
if __name__ == "__main__":
S = "We Are Happy"
print(Solution().replaceSpace1(S))
print(Solution().replaceSpace2(S))
print(Solution().replaceSpace3(S))
06-从尾到头打印链表
不了解Python链表的可以参阅python数据结构-链表
# -*- coding: utf-8 -*-
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
# 返回从尾部到头部的列表值序列,例如[1,2,3]
def printListFromTailToHead(self, listNode):
# write code here
l = []
head = listNode
while head:
l.insert(0, head.val)
head = head.next
return l
if __name__ == '__main__':
# node1 -> node2 -> node3
# node1,node2,node3的val分别为1,2,3
node1 = ListNode(1)
node2 = ListNode(2)
node3 = ListNode(3)
node1.next = node2
node2.next = node3
result = Solution().printListFromTailToHead(node1)
print(result)
07-重建二叉树
# -*- coding: utf-8 -*-
"""
面试题7:重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},
则重建二叉树并返回。
"""
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre, tin):
"""
:param pre: 前序序列
:param tin: 中序序列
:return: 返回树的根root
"""
# write code here
if not pre or not tin: # 如果pre或tin为空则返回None
return None
root = TreeNode(pre[0]) # 前序序列的第一个为根
index = tin.index(pre[0]) # index是判断根在tin中的位置
root.left = self.reConstructBinaryTree(pre[1:index + 1], tin[:index])
root.right = self.reConstructBinaryTree(pre[index + 1:], tin[index + 1:])
return root
if __name__ == '__main__':
# 根据书本上图2.6构建一个二叉树
n8 = TreeNode(8)
n7 = TreeNode(7)
n6 = TreeNode(6)
n5 = TreeNode(5)
n4 = TreeNode(4)
n3 = TreeNode(3)
n2 = TreeNode(2)
n1 = TreeNode(1)
n1.left = n2
n1.right = n3
n2.left = n4
n3.left = n5
n3.right = n6
n4.right = n7
n6.left = n8
pre = [n1, n2, n4, n7, n3, n5, n6, n8] # 前序序列
tin = [n4, n7, n2, n1, n5, n3, n8, n6] # 中序序列
result = Solution().reConstructBinaryTree(pre, tin)
# result实际上是一个树,result.val则是一个树根,依然是TreeNode对象,
# result.val.val才是树根的值
print(result.val.val)
08-二叉树的下一个节点
# -*- coding: utf-8 -*-
"""
面试题8:二叉树的下一个节点
题目描述:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。
注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
"""
class TreeLinkNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
self.next = None # 父节点
class Solution:
def GetNext(self, pNode):
# write code here
if not pNode: # 判断非空
return None
# 1. 有右子树,下一结点是右子树中的最左结点,例如 B,下一结点是 H
if pNode.right:
res = pNode.right
while res.left:
res = res.left
return res
# 2. 无右子树,则向上回溯其父节点
# 2.1 该节点是其父节点的左子树,则该节点的父节点即为所求,例如 H,下一结点是 E
# 2.2 该节点不是其父节点的左子树(换句话说就是其父节点的右子树),则持续回溯其
# 父节点,直到找到一个节点满足其为其父节点的左子树,则其父节点即为所求,比如 I
# 的下一个节点为 A,如果找不到满足条件的这样一节点,比如 G 节点,那么 G 节点
# 就是最后一个节点,他没有下一个节点。
while pNode.next:
tmp = pNode.next
if tmp.left == pNode:
return tmp
pNode = tmp
return None
if __name__ == '__main__':
# 根据书本上图2.8构建一个二叉树
n_a = TreeLinkNode('a')
n_b = TreeLinkNode('b')
n_c = TreeLinkNode('c')
n_d = TreeLinkNode('d')
n_e = TreeLinkNode('e')
n_f = TreeLinkNode('f')
n_g = TreeLinkNode('g')
n_h = TreeLinkNode('h')
n_i = TreeLinkNode('i')
n_a.left = n_b; n_a.right = n_c
n_b.left = n_d; n_b.right = n_e; n_b.next = n_a
n_c.left = n_f; n_c.right = n_g; n_c.next = n_a
n_d.next = n_b
n_e.left = n_h; n_e.right = n_i; n_e.next = n_b
n_f.next = n_c
n_g.next = n_c
n_h.next = n_e
n_i.next = n_e
# 中序遍历 [d, b, h, e, i, a, f, c, g]
testNode = n_g
result = Solution().GetNext(testNode)
if result != None:
print(result.val)
else:
# 如果result为空,说明该node是中序遍历最后一个节点,没有下一个节点
# ,直接输出该节点的val即可
print(testNode.val)
09-01-用两个栈实现队列
# -*- coding: utf-8 -*-
"""
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
"""
"""
解题思路:
https://www.nowcoder.com/profile/4991846/codeBookDetail?submissionId=9811452
<分析>:
入队:将元素进栈A
出队:判断栈B是否为空,如果为空,则将栈A中所有元素pop,并push进栈B,栈B出栈;
如果不为空,栈B直接出栈。
"""
class Solution:
def __init__(self):
self.stack1 = []
self.stack2 = []
def push(self, node):
self.stack1.append(node)
def pop(self):
if self.stack2 == []:
while self.stack1 != []:
self.stack2.append(self.stack1[len(self.stack1) - 1])
self.stack1.pop()
pop = self.stack2[len(self.stack2) - 1]
self.stack2.pop()
return pop
if __name__ == '__main__':
node1 = 'a'
node2 = 'b'
node3 = 'c'
CQueue = Solution()
CQueue.push(node1)
CQueue.push(node2)
CQueue.push(node3)
print(CQueue.pop())
print(CQueue.pop())
print(CQueue.pop())
09-02-用两个队列实现栈
# -*- coding: utf-8 -*-
"""
09题扩展,两个队列实现栈
"""
'''
<分析>:
入栈:将元素进队列A
出栈:判断队列A中元素的个数是否为0,0说明队列A中最后一个元素已经pop
当队列A的长度不为1时,将队列A中的元素依次输送到队列B中,直到队列A只剩1个元素
此时将队列A与队列B互换,则队列B为只有一个元素的队列,该元素即为要出栈的元素
pop该元素即可。
'''
class Solution:
def __init__(self):
self.queue1 = []
self.queue2 = []
def push(self, node):
self.queue1.insert(0, node)
def pop(self):
if not self.queue1: # 如果A空,队列A中无元素,此时return None
return None
while len(self.queue1) != 1:
self.queue2.insert(0, self.queue1.pop())
self.queue1, self.queue2 = self.queue2, self.queue1
return self.queue2.pop()
if __name__ == '__main__':
node1 = 'a'
node2 = 'b'
node3 = 'c'
CStack = Solution()
CStack.push(node1)
CStack.push(node2)
CStack.push(node3)
print(CStack.pop())
print(CStack.pop())
print(CStack.pop())
10-斐波那契数列
# -*- coding: utf-8 -*-
# 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。 # n<=39
# 1、1、2、3、5、8、13、21、34
class Solution:
def Fibonacci(self, n):
# write code here
result = [0, 1]
if n < 2:
return result[n]
fibNMinusOne = 0
fibNMinusTwo = 1
fibN = 0
for i in range(2, n + 1):
fibN = fibNMinusOne + fibNMinusTwo
fibNMinusOne = fibNMinusTwo
fibNMinusTwo = fibN
return fibN
if __name__ == '__main__':
n = 8
F = Solution()
print(F.Fibonacci(n))
10-02-青蛙跳台阶
# -*- coding: utf-8 -*-
# 青蛙跳台阶问题,一只青蛙要跳上n层高的台阶,一次能跳一级,也可以跳两级,请问这只青蛙有多少种跳上这个n层高台阶的方法?
# 1、2、3、5、8、13、21、34
class Solution:
def Fibonacci(self, n):
# write code here
result = [1, 2]
if n < 2:
return result[n]
fibNMinusOne = 1
fibNMinusTwo = 2
fibN = 0
for i in range(2, n):
fibN = fibNMinusOne + fibNMinusTwo
fibNMinusOne = fibNMinusTwo
fibNMinusTwo = fibN
return fibN
if __name__ == '__main__':
n = 8
F = Solution()
print(F.Fibonacci(n))
11-旋转数组的最小数字
# -*- coding: utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
if not rotateArray:
return 0
else:
return min(rotateArray)
def minNumberInRotateArray2(self, rotateArray):
if not rotateArray:
return 0
else:
rotateArray.sort()
return rotateArray[0]
def minNumberInRotateArray3(self, rotateArray):
# write code here
"""
解题思路:> 数组旋转后,分为两部分,前半部分大于等于后半部分(考虑非严格递增的情况)
> 将index1初始化为第一个数字,index2初始化为最后一个数字,mid初始化为第一个数字(应对旋转0个元素的情况)
> 如果index1与index2相邻,此时index2即为所求
> 如果遇到的index1、index2以及indexMid指向的三个数字相等,就无法二分查找,只能遍历数组了
> 如果mid指向的数字大于等于index1指向的数字,那么mid 在数组一中,下一步,将index1往mid挪,指向mid
> 如果mid指向的数字小于等于index2指向的数字,那么mid 在数组二中,下一步,将index2往mid挪,指向mid
:param rotateArray:
:return:
"""
if not rotateArray:
return 0
if len(rotateArray) == 0:
return 0
index1 = 0
index2 = len(rotateArray) - 1
indexMid = index1
while (rotateArray[index1] >= rotateArray[index2]):
if (index2 - index1 == 1): # 如果index2与index1相邻,则index2对应的即为所求
indexMid = index2
break
indexMid = (index1 + index2) // 2
# 如果下标index1、index2以及index3的数值相等,就只能遍历了
if (rotateArray[index1] == rotateArray[index2] and rotateArray[index1] == rotateArray[indexMid]):
return self.minValue(rotateArray, index1, index2)
if (rotateArray[indexMid] >= rotateArray[index1]):
index1 = indexMid
elif (rotateArray[indexMid] <= rotateArray[index2]):
index2 = indexMid
return rotateArray[indexMid]
def minValue(self, rotateArray, index1, index2):
result = rotateArray[index1]
for i in range(index1 + 1, index2 + 1):
if result > rotateArray[i]:
result = rotateArray[i]
return result
if __name__ == '__main__':
array = [3, 4, 5, 1, 2]
a = Solution()
print(a.minNumberInRotateArray(array))
print(a.minNumberInRotateArray2(array))
print(a.minNumberInRotateArray3(array))
12-矩阵中的路径
# -*- coding: utf-8 -*-
"""
// 面试题12:矩阵中的路径
// 题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有
// 字符的路径。路径可以从矩阵中任意一格开始,每一步可以在矩阵中向左、右、
// 上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入
// 该格子。例如在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字
// 母用下划线标出)。但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个
// 字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
// A B T G
// C F C S
// J D E H
"""
import unittest
# -*- coding:utf-8 -*-
class Solution:
def hasPath(self, matrix, rows, cols, path):
"""
:param matrix: 输入的矩阵
:param rows: 矩阵的行数
:param cols: 矩阵的列数
:param path: 要寻找的path
:return:
"""
# write code here
if not matrix or rows < 0 or cols < 0 or path == None:
return False
markmatrix = [0] * (rows * cols)
pathIndex = 0
for row in range(rows):
for col in range(cols):
if self.hasPathCore(matrix, rows, cols, row, col, path, pathIndex, markmatrix):
return True
return False
def hasPathCore(self, matrix, rows, cols, row, col, path, pathIndex, markmatrix):
"""
:param matrix: 输入的矩阵
:param rows: 矩阵行数
:param cols: 矩阵列数
:param row: 当前行
:param col: 当前列
:param path: 要寻找的path
:param pathIndex: 查询到第index个字符
:param markmatrix: mark为已经走过
:return:
"""
if pathIndex == len(path): # 如果pathIndex的长度与path一致,则找到对应的路径
return True
hasPath = False
if row >= 0 and row < rows and col >= 0 and col < cols and matrix[row * cols + col] == path[pathIndex] and not \
markmatrix[row * cols + col]: # 当矩阵行数,列数符合条件,且矩阵上该点存在且等于路径上的那一点,且未被走过
pathIndex += 1 # 路径移到下一个点
markmatrix[row * cols + col] = True # 将刚刚走过的这点mark一下
# 判断该点的上下左右是否满足
hasPath = self.hasPathCore(matrix, rows, cols, row + 1, col, path, pathIndex, markmatrix) or \
self.hasPathCore(matrix, rows, cols, row - 1, col, path, pathIndex, markmatrix) or \
self.hasPathCore(matrix, rows, cols, row, col + 1, path, pathIndex, markmatrix) or \
self.hasPathCore(matrix, rows, cols, row, col - 1, path, pathIndex, markmatrix)
if not hasPath: # 如果上下左右仍未找到对应的点
pathIndex -= 1 # 回到上一步
markmatrix[row * cols + col] = False # 回退之后,走过的路mark为false
return hasPath
class TestSolution(unittest.TestCase):
def test1(self):
matrix = 'ABTGCFCSJDEH'
string = 'BFCE'
rows = 3
cols = 4
solution = Solution()
expected = True
self.assertEqual(expected, solution.hasPath(matrix, rows, cols, string))
def test2(self):
matrix = 'ABCESFCSADEE'
string = 'SEE'
rows = 3
cols = 4
solution = Solution()
expected = True
self.assertEqual(expected, solution.hasPath(matrix, rows, cols, string))
def test3(self):
matrix = 'ABTGCFCSJDEH'
string = 'ABFB'
rows = 3
cols = 4
solution = Solution()
expected = False
self.assertEqual(expected, solution.hasPath(matrix, rows, cols, string))
def test4(self):
matrix = 'ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS'
string = 'SLHECCEIDEJFGGFIE'
rows = 5
cols = 8
solution = Solution()
expected = True
self.assertEqual(expected, solution.hasPath(matrix, rows, cols, string))
def test5(self):
matrix = 'ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS'
string = 'SGGFIECVAASABCEHJIGQEM'
rows = 5
cols = 8
solution = Solution()
expected = True
self.assertEqual(expected, solution.hasPath(matrix, rows, cols, string))
def test6(self):
matrix = 'ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS'
string = 'SGGFIECVAASABCEEJIGOEM'
rows = 5
cols = 8
solution = Solution()
expected = False
self.assertEqual(expected, solution.hasPath(matrix, rows, cols, string))
def test7(self):
matrix = 'ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS'
string = 'SGGFIECVAASABCEHJIGQEMS'
rows = 5
cols = 8
solution = Solution()
expected = False
self.assertEqual(expected, solution.hasPath(matrix, rows, cols, string))
def test8(self):
matrix = 'AAAAAAAAAAAA'
string = 'AAAAAAAAAAAA'
rows = 3
cols = 4
solution = Solution()
expected = True
self.assertEqual(expected, solution.hasPath(matrix, rows, cols, string))
def test9(self):
matrix = 'AAAAAAAAAAAA'
string = 'AAAAAAAAAAAAA'
rows = 3
cols = 4
solution = Solution()
expected = False
self.assertEqual(expected, solution.hasPath(matrix, rows, cols, string))
def test10(self):
matrix = 'A'
string = 'A'
rows = 1
cols = 1
solution = Solution()
expected = True
self.assertEqual(expected, solution.hasPath(matrix, rows, cols, string))
def test11(self):
matrix = 'A'
string = 'B'
rows = 1
cols = 1
solution = Solution()
expected = False
self.assertEqual(expected, solution.hasPath(matrix, rows, cols, string))
def test12(self):
matrix = ''
string = ''
rows = 0
cols = 0
solution = Solution()
expected = False
self.assertEqual(expected, solution.hasPath(matrix, rows, cols, string))
if __name__ == '__main__':
unittest.main()
13-机器人的运动范围
# -*- coding: utf-8 -*-
"""
// 面试题13:机器人的运动范围
// 题目:地上有一个m行n列的方格。一个机器人从坐标(0, 0)的格子开始移动,它
// 每一次可以向左、右、上、下移动一格,但不能进入行坐标和列坐标的数位之和
// 大于k的格子。例如,当k为18时,机器人能够进入方格(35, 37),因为3+5+3+7=18。
// 但它不能进入方格(35, 38),因为3+5+3+8=19。请问该机器人能够到达多少个格子?
"""
# 牛客网题解:https://www.nowcoder.com/questionTerminal/6e5207314b5241fb83f2329e89fdecc8?answerType=1&f=discussion
# 思路:这道题跟前一道题一样,也是回溯法,分析题目,我们需要两个全局变量:标志数组和计数变量;
# 需要一个函数来计算行坐标和列坐标的数位之和;终止条件包括三种情况:越界、重复、行坐标和列坐标的数位之和超过k,
# 然后流程和上一道题相同。
# 根据需求分析需要的函数或变量
# - 标志数组markmatrix和计数变量count
# - 计算行列坐标数位之和的函数
# - 包含计数与处理终止条件的函数
class Solution:
def movingCount(self, threshold, rows, cols):
if threshold < 0 or rows <= 0 or cols <= 0:
return 0
markmatrix = [False] * (rows * cols)
count = self.movingCountCore(threshold, rows, cols, 0, 0, markmatrix)
return count
def movingCountCore(self, threshold, rows, cols, row, col, markmatrix):
value = 0
if self.check(threshold, rows, cols, row, col, markmatrix):
markmatrix[row * cols + col] = True
value = 1 + self.movingCountCore(threshold, rows, cols, row + 1, col, markmatrix) + \
self.movingCountCore(threshold, rows, cols, row - 1, col, markmatrix) + \
self.movingCountCore(threshold, rows, cols, row, col + 1, markmatrix) + \
self.movingCountCore(threshold, rows, cols, row, col - 1, markmatrix)
return value
def check(self, threhold, rows, cols, row, col, markmatrix):
if (row >= 0 and row < rows and col >= 0 and col < cols and self.getDigitSum(row) + self.getDigitSum(
col) <= threhold and not markmatrix[row * cols + col]):
return True
return False
def getDigitSum(self, number):
sum = 0
while (number > 0):
sum += number % 10
number //= 10
return sum
if __name__ == '__main__':
solution = Solution()
print(solution.movingCount(5, 10, 10))
14-剪绳子
# -*- coding: utf-8 -*-
class Solution:
def cutRope(self, number):
# write code here
# 动态规划
if (number < 2):
return 0
if (number == 2):
return 1
if (number == 3):
return 2
products = [0] * (number + 1)
products[0] = 0
products[1] = 1
products[2] = 2
products[3] = 3
max = 0
for i in range(4, number + 1):
max = 0
for j in range(1, i // 2 + 1):
product = products[j] * products[i - j]
if (max < product):
max = product
products[i] = max
max = products[number]
return max
def cutRope2(self, number):
# 贪心算法
if number < 2:
return 0
if number == 2:
return 1
if number == 3:
return 2
timesOf3 = number // 3
if number - timesOf3 * 3 == 1:
timesOf3 -= 1
timesOf2 = (number - timesOf3 * 3) // 2
return int(pow(3, timesOf3)) * int(pow(2, timesOf2))
if __name__ == '__main__':
length = 8
so = Solution()
print(so.cutRope(length))
print(so.cutRope2(length))
15-位运算
# -*- coding: utf-8 -*-
"""
// 面试题15:二进制中1的个数
// 题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如
// 把9表示成二进制是1001,有2位是1。因此如果输入9,该函数输出2。
"""
class Solution:
def NumberOf1(self, n):
# 最佳解法
count = 0
if n < 0: # 如果该整数是负数,要把它和0xffffffff相与,消除负数的影响。
n = n & 0xffffffff
while n:
n = (n - 1) & n
count += 1
return count
def NumberOf1_2(self, n):
# 解法2 使用python特性
return bin(n & 0xffffffff).count("1")
if __name__ == '__main__':
so = Solution()
print(so.NumberOf1(9))
print(so.NumberOf1_2(9))