剑指offer

剑指offer Python实现

 
 
  1. 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
  2. # -*- coding:utf-8 -*-
  3. class Solution:
  4. # array 二维列表
  5. def Find(self, target, array):
  6. # write code here
  7. if not array:
  8. return False
  9. row = len(array)
  10. col = len(array[0])
  11. i = 0
  12. j = col-1
  13. while i < row and j >= 0:
  14. if array[i][j] > target:
  15. j -= 1
  16. elif array[i][j] < target:
  17. i += 1
  18. else:
  19. return True
  20. return False
 
 
  1. 请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy
  2. class Solution:
  3. # s 源字符串
  4. def replaceSpace(self, s):
  5. # write code here
  6. """
  7. s = s.replace(" ", "%20")
  8. return s
  9. """
  10. # 先统计空格的数量
  11. num_space = 0
  12. for i in s:
  13. if i == " ":
  14. num_space += 1
  15. l = len(s)
  16. replace_s = [None for _ in range(l + 2 * num_space)]
  17. i = l-1
  18. j = len(replace_s)-1
  19. while i >= 0:
  20. if s[i] != " ":
  21. replace_s[j] = s[i]
  22. j -= 1
  23. else:
  24. replace_s[j] = '0'
  25. j -= 1
  26. replace_s[j] = '2'
  27. j -= 1
  28. replace_s[j] = '%'
  29. j -= 1
  30. i -= 1
  31. return "".join(replace_s)
 
 
  1. 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList
  2. class Solution:
  3. # 返回从尾部到头部的列表值序列,例如[1,2,3]
  4. def printListFromTailToHead(self, listNode):
  5. """
  6. # write code here
  7. # 采用栈存储数据
  8. res = []
  9. while listNode:
  10. res.insert(0, listNode.val)
  11. listNode = listNode.next
  12. return res
  13. """
  14. '''
  15. # 直接采用递归的方法
  16. res = []
  17. def add_list(listNode):
  18. if not listNode:
  19. return
  20. add_list(listNode.next)
  21. res.append(listNode.val)
  22. add_list(listNode)
  23. return res
  24. '''
  25. # 直接采用递归的方法
  26. def add_list(listNode, res):
  27. if not listNode:
  28. return res
  29. res = add_list(listNode.next, res)
  30. res.append(listNode.val)
  31. return res
  32. return add_list(listNode, [])
 
 
  1. 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
  2. class Solution:
  3. # 返回构造的TreeNode根节点
  4. def reConstructBinaryTree(self, pre, tin):
  5. # write code here
  6. if len(pre)>0:
  7. # 根节点必定在pre的第一个数
  8. root = TreeNode(pre[0])
  9. # 在中序遍历数列中找到树根节点位置
  10. root_id = tin.index(pre[0])
  11. # 由于先序遍历的第一个是中序遍历的最后一个(子树中), 所以pre从1开始,tin从root_id-1结束
  12. root.left = self.reConstructBinaryTree(pre[1:1+root_id], tin[:root_id])
  13. root.right = self.reConstructBinaryTree(pre[1+root_id:], tin[root_id+1:])
  14. return root
 
 
  1. 用两个栈来实现一个队列,完成队列的PushPop操作。 队列中的元素为int类型。
  2. class Solution:
  3. def __init__(self):
  4. self.s1 = []
  5. self.s2 = []
  6. def push(self, node):
  7. # write code here
  8. self.s1.append(node)
  9. def pop(self):
  10. # return xx
  11. if self.s2:
  12. return self.s2.pop()
  13. else:
  14. # 将s1中的数据依次取出放入s2中
  15. while self.s1:
  16. self.s2.append(self.s1.pop())
  17. return self.s2.pop()
 
 
  1. 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0
  2. class Solution:
  3. def minNumberInRotateArray(self, rotateArray):
  4. # write code here
  5. def getMin(low,high,arr):
  6. if low > high:
  7. return 0
  8. if low == high:
  9. return arr[low]
  10. mid = (low+high)//2
  11. if arr[mid-1] > arr[mid]:
  12. return arr[mid]
  13. elif arr[mid] > arr[mid+1]:
  14. return arr[mid+1]
  15. elif arr[mid] < arr[high]:
  16. return getMin(low, mid-1, arr)
  17. elif arr[mid] > arr[low]:
  18. return getMin(mid+1, high, arr)
  19. else:
  20. return min(getMin(mid+1, high, arr), getMin(low, mid-1, arr))
  21. return getMin(0, len(rotateArray)-1, rotateArray)
 
 
  1. 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
  2. n<=39
  3. class Solution:
  4. def Fibonacci(self, n):
  5. if n == 0:
  6. return 0
  7. if n == 1:
  8. return 1
  9. # write code here
  10. fibNMinusOne = 0
  11. fibNMinusTwo = 1
  12. res = 0
  13. for i in range(2, n+1):
  14. res = fibNMinusOne + fibNMinusTwo
  15. fibNMinusOne = fibNMinusTwo
  16. fibNMinusTwo = res
  17. return res
 
 
  1. 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
  2. class Solution:
  3. def jumpFloor(self, number):
  4. # write code here
  5. if number <= 0:
  6. return 0
  7. res = [1, 2]
  8. if number == 1:
  9. return res[0]
  10. if number == 2:
  11. return res[1]
  12. minus1 = 1
  13. minus2 = 2
  14. for i in range(3, number+1):
  15. res = minus1 + minus2
  16. minus1 = minus2
  17. minus2 = res
  18. return res
 
 
  1. 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
  2. class Solution:
  3. def jumpFloorII(self, number):
  4. # write code here
  5. if number <= 0:
  6. return 0
  7. if number == 1:
  8. return 1
  9. if number == 2:
  10. return 2
  11. minus = 2
  12. for i in range(3, number+1):
  13. res = 2*minus
  14. minus = res
  15. return res
 
 
  1. 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
  2. class Solution:
  3. def rectCover(self, number):
  4. # write code here
  5. if number <= 0:
  6. return 0
  7. if number == 1:
  8. return 1
  9. if number == 2:
  10. return 2
  11. minus1 = 1
  12. minus2 = 2
  13. res = 0
  14. for i in range(3, number+1):
  15. res = minus1 + minus2
  16. minus1 = minus2
  17. minus2 = res
  18. return res
 
 
  1. 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
  2. class Solution:
  3. def NumberOf1(self, n):
  4. # write code here
  5. '''
  6. count = 0
  7. # 由于这里有32,所以不会陷入死循环的状态
  8. for i in range(32):
  9. count += (1 & n>>i)
  10. return count
  11. #return sum([(n>>i & 1) for i in range(0,32)])
  12. '''
  13. count = 0
  14. # 由于python是动态语言,所以数的大小会根据需要自动改变,这里需要控制为32位
  15. while (n & 0xffffffff):
  16. count += 1
  17. n = (n-1) & n
  18. return count
 
 
  1. 给定一个double类型的浮点数baseint类型的整数exponent。求baseexponent次方。
  2. class Solution:
  3. def Power(self, base, exponent):
  4. # write code here
  5. # return base**exponent
  6. if base == 0 and exponent < 0:
  7. # 无意义
  8. return 0
  9. res = 1
  10. i = 1
  11. abs_exponent = abs(exponent)
  12. while i <= abs_exponent:
  13. res *= base
  14. i += 1
  15. if exponent <= 0:
  16. return 1/res
  17. else:
  18. return res
 
 
  1. 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
  2. class Solution:
  3. def reOrderArray(self, array):
  4. # write code here
  5. '''
  6. # 采用冒泡算法排序
  7. for i in range(len(array)-1):
  8. for j in range(0, len(array)-i-1):
  9. if array[j] % 2 == 0 and array[j+1] % 2 == 1:
  10. array[j], array[j+1] = array[j+1], array[j]
  11. return array
  12. '''
  13. # 采用额外数组法
  14. res = []
  15. l = len(array)
  16. for i in range(len(array)):
  17. if array[l-i-1] % 2 != 0:
  18. res.insert(0, array[l-i-1])
  19. if array[i] % 2 == 0:
  20. res.append(array[i])
  21. return res
 
 
  1. 输入一个链表,输出该链表中倒数第k个结点。
  2. class Solution:
  3. def FindKthToTail(self, head, k):
  4. # write code here
  5. if not head:
  6. return
  7. # python中的数据是没有头结点的
  8. l1 = head
  9. l2 = l1
  10. i = 0
  11. while i < k:
  12. l2 = l2.next
  13. i += 1
  14. if not l2 and i < k:
  15. return
  16. while l2:
  17. l1 = l1.next
  18. l2 = l2.next
  19. return l1
 
 
  1. 输入一个链表,反转链表后,输出新链表的表头。
  2. class Solution:
  3. # 返回ListNode
  4. def ReverseList(self, pHead):
  5. # write code here
  6. # 就地转换法
  7. if not pHead:
  8. return
  9. pre = pHead
  10. cur = pHead.next
  11. pHead.next = None
  12. while cur:
  13. next = cur.next
  14. cur.next = pre
  15. pre = cur
  16. cur = next
  17. return pre
 
 
  1. 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
  2. class Solution:
  3. # 返回合并后列表
  4. def Merge(self, pHead1, pHead2):
  5. # write code here
  6. if not pHead1:
  7. return pHead2
  8. if not pHead2:
  9. return pHead1
  10. head = pHead1
  11. pre = pHead1
  12. next_p = pHead2.next
  13. while pHead1 and pHead2:
  14. if pHead1.val <= pHead2.val:
  15. pre = pHead1
  16. pHead1 = pHead1.next
  17. else:
  18. pre.next = pHead2
  19. pHead2.next = pHead1
  20. pre = pHead1
  21. pHead1 = pHead1.next
  22. pHead2 = next_p
  23. if pHead2:
  24. next_p = pHead2.next
  25. # 判断是哪个指针为None
  26. if not pHead1:
  27. pre.next = pHead2
  28. return head
  29. if not pHead2:
  30. return head
 
 
  1. 输入两棵二叉树AB,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
  2. class Solution:
  3. def HasSubtree(self, pRoot1, pRoot2):
  4. # write code here
  5. if not pRoot2 or not pRoot1:
  6. return False
  7. return self.is_subtree(pRoot1, pRoot2) or self.HasSubtree(pRoot1.left, pRoot2) or self.HasSubtree(pRoot1.right, pRoot2)
  8. def is_subtree(self, A, B):
  9. if not B:
  10. return True
  11. if not A or A.val != B.val:
  12. return False
  13. return self.is_subtree(A.left, B.left) and self.is_subtree(A.right, B.right)
 
 
  1. 操作给定的二叉树,将其变换为源二叉树的镜像。
  2. class Solution:
  3. # 返回镜像树的根节点
  4. def Mirror(self, root):
  5. # write code here
  6. if root:
  7. tmp = root.left
  8. root.left = root.right
  9. root.right = tmp
  10. self.Mirror(root.left)
  11. self.Mirror(root.right)
 
 
  1. 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下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.
  2. class Solution:
  3. # matrix类型为二维列表,需要返回列表
  4. def printMatrix(self, matrix):
  5. # write code here
  6. if not matrix:
  7. return matrix
  8. res = []
  9. startX = 0
  10. while len(matrix) > 2*startX and len(matrix[0]) > 2*startX:
  11. res.extend(self.print_matrix_incircle(matrix, startX))
  12. startX += 1
  13. return res
  14. def print_matrix_incircle(self, matrix, start):
  15. res = []
  16. endX = len(matrix[0]) - 1 -start
  17. endY = len(matrix) - 1 - start
  18. # 从左往右打印,没有约束条件
  19. for i in range(start, endX+1):
  20. print(matrix[start][i])
  21. res.append(matrix[start][i])
  22. # 从上往下打印,至少有两行
  23. if endY > start:
  24. for i in range(start+1, endY+1):
  25. print(matrix[i][endX])
  26. res.append(matrix[i][endX])
  27. # 从右往左打印,至少有两行两列
  28. if start < endX and endY > start:
  29. for i in range(endX-1, start-1, -1):
  30. print(matrix[endY][i])
  31. res.append(matrix[endY][i])
  32. # 从下往上打印,至少有三行两列
  33. if start < endY-1 and start<endX:
  34. for i in range(endY-1, start, -1):
  35. print(matrix[i][start])
  36. res.append(matrix[i][start])
  37. return res
 
 
  1. 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O1))。
  2. # -*- coding:utf-8 -*-
  3. class Solution:
  4. def __init__(self):
  5. self.stack = []
  6. self.stack2 = []
  7. def push(self, node):
  8. # write code here
  9. self.stack.append(node)
  10. if not self.stack2:
  11. self.stack2.append(node)
  12. elif node <= self.stack2[-1]:
  13. self.stack2.append(node)
  14. def pop(self):
  15. # write code here
  16. if self.stack[-1] == self.stack2[-1]:
  17. self.stack2.pop()
  18. return self.stack.pop()
  19. def top(self):
  20. # write code here
  21. return self.stack[-1]
  22. def min(self):
  23. # write code here
  24. return self.stack2[-1]
 
 
  1. 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
  2. class Solution:
  3. def IsPopOrder(self, pushV, popV):
  4. # write code here
  5. if len(pushV) != len(popV):
  6. return False
  7. i = 0
  8. j = 0
  9. stack = []
  10. while i < len(pushV):
  11. stack.append(pushV[i])
  12. i += 1
  13. while stack and stack[-1] == popV[j]:
  14. stack.pop()
  15. j += 1
  16. #return not stack and j == len(popV)
  17. return not stack
 
 
  1. 从上往下打印出二叉树的每个节点,同层节点从左至右打印。
  2. from collections import deque
  3. class Solution:
  4. # 返回从上到下每个节点值列表,例:[1,2,3]
  5. def PrintFromTopToBottom(self, root):
  6. # write code here
  7. if not root:
  8. return []
  9. res = []
  10. queue = deque()
  11. queue.append(root)
  12. while queue:
  13. root = queue.popleft()
  14. res.append(root.val)
  15. if root.left:
  16. queue.append(root.left)
  17. if root.right:
  18. queue.append(root.right)
  19. return res
 
 
  1. 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
  2. class Solution:
  3. def VerifySquenceOfBST(self, sequence):
  4. # write code here
  5. if not sequence:
  6. return False
  7. if len(sequence) == 1:
  8. return True
  9. root = sequence[-1]
  10. i = 0
  11. while i < len(sequence)-1:
  12. if sequence[i] > root:
  13. break
  14. i += 1
  15. j = i
  16. # 判断后面的数是否都大于root值
  17. while j < len(sequence)-1:
  18. if sequence[j] < root:
  19. return False
  20. j += 1
  21. if i == 0:
  22. return self.VerifySquenceOfBST(sequence[i:len(sequence)-1])
  23. elif i == len(sequence) - 1:
  24. return self.VerifySquenceOfBST(sequence[:i])
  25. else:
  26. return self.VerifySquenceOfBST(sequence[:i]) and self.VerifySquenceOfBST(sequence[i:len(sequence)-1])
 
 
  1. 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
  2. class Solution:
  3. # 返回二维列表,内部每个列表表示找到的路径
  4. def FindPath(self, root, expectNumber):
  5. # write code here
  6. res = []
  7. def equal_path(root, expectNumber, path, res):
  8. if not root:
  9. return
  10. path.append(root.val)
  11. if not root.left or not root.right:
  12. if sum(path) == expectNumber:
  13. res.append([i for i in path])
  14. equal_path(root.left, expectNumber, path, res)
  15. equal_path(root.right, expectNumber, path, res)
  16. path.pop()
  17. equal_path(root, expectNumber, [], res)
  18. return res
 
 
  1. 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
  2. class Solution:
  3. # 返回 RandomListNode
  4. def Clone(self, pHead):
  5. # write code here
  6. '''
  7. # 空间换时间的方法
  8. if not pHead:
  9. return pHead
  10. source_copy = {}
  11. copy_head = RandomListNode(pHead.label)
  12. source_copy[id(pHead)] = copy_head
  13. copy_normal_p = copy_head
  14. normal_p = pHead.next
  15. # 对节点进行复制
  16. while normal_p:
  17. node = RandomListNode(normal_p.label)
  18. source_copy[id(normal_p)] = node
  19. copy_normal_p.next = node
  20. copy_normal_p = node
  21. normal_p = normal_p.next
  22. # 对特殊指针进行复制
  23. special_p = pHead
  24. copy_special_p = copy_head
  25. while special_p:
  26. if special_p.random:
  27. copy_special_p.random = source_copy[id(special_p.random)]
  28. special_p = special_p.next
  29. copy_special_p = copy_special_p.next
  30. return copy_head
  31. '''
  32. if not pHead:
  33. return pHead
  34. self.insert(pHead)
  35. self.dup_random(pHead)
  36. return self.split(pHead)
  37. # 嵌入-复制-分离法
  38. # 将复制主干内容嵌入原链表
  39. def insert(self, pHead):
  40. pre = pHead
  41. while pre:
  42. back = pre.next
  43. node = RandomListNode(pre.label)
  44. pre.next = node
  45. node.next = back
  46. pre = back
  47. # 复制随机指针
  48. def dup_random(self, pHead):
  49. pre = pHead
  50. dup = pHead.next
  51. while dup.next:
  52. if pre.random:
  53. dup.random = pre.random.next
  54. if dup.next:
  55. dup = dup.next.next
  56. pre = pre.next.next
  57. # 分离链表
  58. def split(self, pHead):
  59. '''
  60. pNode=pHead
  61. #pClonedHead=None
  62. #pCloned=None
  63. if pHead:
  64. pClonedHead=pCloned=pNode.next
  65. pNode.next=pCloned.next
  66. pNode=pCloned.next
  67. while pNode:
  68. pCloned.next=pNode.next
  69. pCloned=pCloned.next
  70. pNode.next=pCloned.next
  71. pNode=pNode.next
  72. return pClonedHead
  73. '''
  74. # 在分开链表的时候,必须把最后一个连接也要去掉,不去掉所以出了很大的问题
  75. pNode = pHead
  76. pCloneHead= pClone = pNode.next
  77. while pClone.next:
  78. pNode.next = pClone.next
  79. pNode = pClone.next
  80. pClone.next = pNode.next
  81. pClone = pNode.next
  82. # 切断最后一个连接
  83. pNode.next = None
  84. return pCloneHead
 
 
  1. 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
  2. class Solution:
  3. def __init__(self):
  4. self.pHead = None
  5. self.pEnd = None
  6. def Convert(self, pRootOfTree):
  7. # write code here
  8. if not pRootOfTree:
  9. return
  10. self.Convert(pRootOfTree.left)
  11. pRootOfTree.left = self.pEnd
  12. if not self.pHead:
  13. self.pHead = pRootOfTree
  14. else:
  15. self.pEnd.right = pRootOfTree
  16. self.pEnd = pRootOfTree
  17. self.Convert(pRootOfTree.right)
  18. return self.pHead
 
 
  1. 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cabcba
  2. class Solution:
  3. def Permutation(self, ss):
  4. # write code here
  5. if not ss:
  6. return []
  7. ss = list(ss)
  8. res = []
  9. self.perm(ss, res, 0)
  10. uniq = list(set(res))
  11. return sorted(uniq)
  12. def perm(self, ss, res, start):
  13. if start == len(ss)-1:
  14. res.append("".join(ss))
  15. else:
  16. i = start
  17. while i < len(ss):
  18. ss[i], ss[start] = ss[start], ss[i]
  19. self.perm(ss, res, start+1)
  20. ss[i], ss[start] = ss[start], ss[i]
  21. i += 1
 
 
  1. 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0
  2. class Solution:
  3. def MoreThanHalfNum_Solution(self, numbers):
  4. # write code here
  5. '''
  6. # 方法一:采用空间换时间
  7. count_dic = {}
  8. for i in range(len(numbers)):
  9. count_dic[numbers[i]] = count_dic.get(numbers[i], 0) + 1
  10. if count_dic[numbers[i]] > len(numbers) >> 1:
  11. return numbers[i]
  12. return 0
  13. '''
  14. # 方法二:采用partition方法,类快排的方法,找到中位数
  15. begin = 0
  16. end = len(numbers) - 1
  17. return self.get_more_than_half(numbers, begin, end)
  18. def get_more_than_half(self, numbers, begin, end):
  19. index = self.partition(numbers, begin, end)
  20. while index != len(numbers) >> 1:
  21. if index < len(numbers) >> 1:
  22. index = self.partition(numbers,index+1, end)
  23. elif index > len(numbers) >> 1:
  24. index = self.partition(numbers, begin, index-1)
  25. count = 0
  26. for i in range(len(numbers)):
  27. if numbers[i] == numbers[index]:
  28. count += 1
  29. return numbers[index] if count > len(numbers) >> 1 else 0
  30. def partition(self, numbers, begin, end):
  31. index = begin
  32. key = numbers[index]
  33. while begin < end:
  34. while begin < end and numbers[end] >= key:
  35. end -= 1
  36. numbers[begin] = numbers[end]
  37. while begin < end and numbers[begin] <= key:
  38. begin += 1
  39. numbers[end] = numbers[begin]
  40. numbers[begin] = key
  41. return begin
 
 
  1. 输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,88个数字,则最小的4个数字是1,2,3,4,。
  2. class Solution:
  3. def GetLeastNumbers_Solution(self, tinput, k):
  4. # write code here
  5. # 采用partition的方法
  6. if k == 0 or len(tinput) < k:
  7. #if not tinput or k == 0 or len(tinput) < k:
  8. return []
  9. start = 0
  10. end = len(tinput) -1
  11. index = self.partition(tinput, start, end)
  12. while index != k-1:
  13. if index > k-1:
  14. index = self.partition(tinput, start, index-1)
  15. elif index < k-1:
  16. index = self.partition(tinput, index+1, end)
  17. res = sorted(tinput[:k])
  18. return res
  19. def partition(self, tinput, start, end):
  20. key = tinput[start]
  21. while start < end:
  22. if start < end and tinput[end] >= key:
  23. end -= 1
  24. tinput[start] = tinput[end]
  25. if start < end and tinput[start] <= key:
  26. start += 1
  27. tinput[end] = tinput[start]
  28. tinput[start] = key
  29. return start
 
 
  1. HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
  2. class Solution:
  3. def FindGreatestSumOfSubArray(self, array):
  4. # write code here
  5. if not array:
  6. return 0
  7. nEnd = array[0]
  8. nAll = array[0]
  9. for i in range(1, len(array)):
  10. if nEnd + array[i] < array[i]:
  11. nEnd = array[i]
  12. else:
  13. nEnd += array[i]
  14. nAll = max(nEnd, nAll)
  15. return nAll
 
 
  1. 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有110111213因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 n 1出现的次数)。
  2. class Solution:
  3. def NumberOf1Between1AndN_Solution(self, n):
  4. # write code here
  5. res = 0
  6. while True:
  7. # 首先判断n的位数
  8. n_copy = n
  9. count = 0
  10. while n_copy:
  11. n_copy //= 10
  12. count += 1
  13. middle_num = 0
  14. for i in range(count - 1):
  15. middle_num += n // (10 ** i) % 10 * 10**i
  16. res += self.get_count_1(n, count, middle_num)
  17. n = middle_num
  18. if n < 2:
  19. break
  20. return res
  21. def get_count_1(self, n, count, middle_num):
  22. if n > 0 and n < 10:
  23. return 1
  24. if n < 1:
  25. return 0
  26. num = 0
  27. copy_n = n
  28. count_copy = count
  29. while count_copy > 1:
  30. copy_n //= 10
  31. count_copy -= 1
  32. if copy_n > 1:
  33. num += 10 ** (count - 1)
  34. else:
  35. num += middle_num+1
  36. num += copy_n * (count - 1) * 10 ** (count - 2)
  37. return num
 
 
  1. 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{332321},则打印出这三个数字能排成的最小数字为321323
  2. class Solution:
  3. def PrintMinNumber(self, numbers):
  4. # write code here
  5. return "".join(sorted([str(i) for i in numbers], cmp = lambda x, y: int(x+y) - int(y+x)))
 
 
  1. 把只包含质因子235的数称作丑数(Ugly Number)。例如68都是丑数,但14不是,因为它包含质因子7 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
  2. class Solution:
  3. def GetUglyNumber_Solution(self, index):
  4. # write code here
  5. if index < 1:
  6. return 0
  7. ugly_number = [1]
  8. if index == 1:
  9. return 1
  10. m2 = 0
  11. m3 = 0
  12. m5 = 0
  13. i = 1
  14. while i < index:
  15. num = min(ugly_number[m2]*2, ugly_number[m3]*3, ugly_number[m5]*5)
  16. ugly_number.append(num)
  17. # 这里的if不能用elif,有可能该数为2或者3或者5的最小公倍数
  18. if ugly_number[m2]*2 <= num:
  19. m2 += 1
  20. if ugly_number[m3]*3 <= num:
  21. m3 += 1
  22. if ugly_number[m5]*5 <= num:
  23. m5 += 1
  24. i += 1
  25. return ugly_number[-1]
 
 
  1. 在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).
  2. class Solution:
  3. def FirstNotRepeatingChar(self, s):
  4. # write code here
  5. # 建立hash表,第一次遍历s添加次数到hash表,第二次遍历s找到第一个只出现一次的字符
  6. res = {}
  7. for i in s:
  8. res[i] = res.get(i, 0) + 1
  9. for i in s:
  10. if res[i] == 1:
  11. return s.index(i)
  12. return -1
 
 
  1. 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P1000000007取模的结果输出。 即输出P%1000000007
  2. class Solution:
  3. def InversePairs(self, data):
  4. # write code here
  5. if not data:
  6. return 0
  7. data_copy = [i for i in data]
  8. count = self.InversePairsCore(data, data_copy, 0, len(data)-1)
  9. return count% 1000000007
  10. def InversePairsCore(self, data, data_copy, start, end):
  11. if start == end:
  12. data_copy[start] = data[start]
  13. return 0
  14. length = (end-start)//2
  15. left = self.InversePairsCore(data_copy, data, start, start+length)
  16. right = self.InversePairsCore(data_copy, data, start+length+1, end)
  17. i = start+length
  18. j = end
  19. indexCopy = end
  20. count = 0
  21. while i>=start and j >=start+length+1:
  22. if data[i]>data[j]:
  23. data_copy[indexCopy] = data[i]
  24. indexCopy -= 1
  25. i -= 1
  26. count += j-start-length
  27. else:
  28. data_copy[indexCopy] = data[j]
  29. indexCopy -= 1
  30. j -= 1
  31. while i >= start:
  32. data_copy[indexCopy] = data[i]
  33. i -= 1
  34. indexCopy -= 1
  35. while j >= start+length+1:
  36. data_copy[indexCopy] = data[j]
  37. j -= 1
  38. indexCopy -= 1
  39. return left + right + count
 
 
  1. 输入两个链表,找出它们的第一个公共结点。
  2. class Solution:
  3. def FindFirstCommonNode(self, pHead1, pHead2):
  4. # write code here
  5. if not pHead1 or not pHead2:
  6. return None
  7. l1 = 0
  8. l2 = 0
  9. p1 = pHead1
  10. p2 = pHead2
  11. while p1:
  12. p1 = p1.next
  13. l1 += 1
  14. while p2:
  15. p2 = p2.next
  16. l2 += 1
  17. if l1 > l2:
  18. i = 0
  19. while i < abs(l1-l2):
  20. pHead1= pHead1.next
  21. i += 1
  22. while pHead1 and pHead2:
  23. if pHead1 == pHead2:
  24. return pHead1
  25. else:
  26. pHead1 = pHead1.next
  27. pHead2 = pHead2.next
  28. else:
  29. i = 0
  30. while i < abs(l1-l2):
  31. pHead2 = pHead2.next
  32. i += 1
  33. while pHead1 and pHead2:
  34. if pHead1 == pHead2:
  35. return pHead2
  36. else:
  37. pHead1 = pHead1.next
  38. pHead2 = pHead2.next
  39. return None
 
 
  1. 统计一个数字在排序数组中出现的次数。
  2. # -*- coding:utf-8 -*-
  3. class Solution:
  4. def GetNumberOfK(self, data, k):
  5. # write code here
  6. if not data:
  7. return 0
  8. start = 0
  9. # end指针为数组下标
  10. end = len(data)-1
  11. flag = 0
  12. while start <= end:
  13. mid = (start+end) >> 1
  14. if data[mid] > k:
  15. end = mid-1
  16. elif data[mid] < k:
  17. start = mid+1
  18. else:
  19. flag = 1
  20. break
  21. if flag == 0:
  22. return 0
  23. count = 0
  24. i = mid
  25. while i >= 0 and data[i] == k:
  26. count += 1
  27. i -= 1
  28. j = mid+1
  29. while j < len(data) and data[j] == k:
  30. count += 1
  31. j += 1
  32. return count
 
 
  1. 输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
  2. class Solution:
  3. def TreeDepth(self, pRoot):
  4. # write code here
  5. if not pRoot:
  6. return 0
  7. return max(1 + self.TreeDepth(pRoot.left), 1 + self.TreeDepth(pRoot.right))
 
 
  1. 输入一棵二叉树,判断该二叉树是否是平衡二叉树。
  2. class Solution:
  3. def IsBalanced_Solution(self, pRoot):
  4. # write code here
  5. '''
  6. if not pRoot:
  7. return True
  8. return self.IsBanlanced(pRoot) and self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right)
  9. def IsBanlanced(self, pRoot):
  10. if abs(self.height(pRoot.left) - self.height(pRoot.right)) <= 1:
  11. return True
  12. else:
  13. return False
  14. def height(self, pRoot):
  15. if not pRoot:
  16. return 0
  17. return max(1+self.height(pRoot.left), 1+self.height(pRoot.right))
  18. '''
  19. # 通过后续遍历自下往上进行遍历
  20. return self.dfs(pRoot) != -1
  21. def dfs(self, pRoot):
  22. if not pRoot:
  23. return 0
  24. left = self.dfs(pRoot.left)
  25. if left == -1:
  26. return -1
  27. right = self.dfs(pRoot.right)
  28. if right == -1:
  29. return -1
  30. if abs(left-right) > 1:
  31. return -1
  32. return max(left, right) + 1
 
 
  1. 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
  2. class Solution:
  3. # 返回[a,b] 其中ab是出现一次的两个数字
  4. def FindNumsAppearOnce(self, array):
  5. # write code here
  6. c = 0
  7. #for i in array:
  8. # c ^= i
  9. c = reduce(lambda x, y: x^y, array)
  10. k = 0
  11. d = c
  12. while d & 1 != 1:
  13. k += 1
  14. d = d >> 1
  15. s = []
  16. for i in array:
  17. if i >> k & 1 == 1:
  18. s.append(i)
  19. e = 0
  20. e = reduce(lambda x, y: x^y, s)
  21. return [c^e, e]
 
 
  1. 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
  2. class Solution:
  3. def FindContinuousSequence(self, tsum):
  4. # write code here
  5. # 建立二维数组
  6. sequence_sum = [[0] * (tsum / 2 + 1) for _ in range(tsum / 2 + 1)]
  7. # 为对角线数据赋予初始值
  8. for i in range(tsum / 2 + 1):
  9. sequence_sum[i][i] = i + 1
  10. # 动态规划填充数组信息,并记录为100的数量
  11. res = []
  12. for i in range(1, tsum / 2 + 1):
  13. for j in range(i):
  14. sequence_sum[i][j] = sequence_sum[i - 1][j] + (i + 1)
  15. if sequence_sum[i][j] == tsum:
  16. res.append(range(j+1, i + 2))
  17. return res
 
 
  1. 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
  2. class Solution:
  3. def FindNumbersWithSum(self, array, tsum):
  4. # write code here
  5. if not isinstance(array, list):
  6. return []
  7. res = []
  8. begin = 0
  9. end = len(array)-1
  10. while begin < end:
  11. if array[begin] + array[end] > tsum:
  12. end -= 1
  13. elif array[begin] + array[end] < tsum:
  14. begin += 1
  15. else:
  16. # 通过数学公式证明,边缘的两个数字乘积一定小于中间两个数字乘积
  17. return [array[begin], array[end]]
  18. return []
 
 
  1. 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!
  2. class Solution:
  3. def LeftRotateString(self, s, n):
  4. # write code here
  5. '''
  6. # 空间换时间
  7. if not s:
  8. return ""
  9. n %= len(s)
  10. return s[n:]+s[:n]
  11. '''
  12. # 翻转法
  13. if not s:
  14. return ""
  15. s = list(s)
  16. n %= len(s)
  17. begin = 0
  18. end = n-1
  19. while begin < end:
  20. s[begin], s[end] = s[end], s[begin]
  21. begin += 1
  22. end -= 1
  23. begin = n
  24. end = len(s)-1
  25. while begin < end:
  26. s[begin], s[end] = s[end], s[begin]
  27. begin += 1
  28. end -= 1
  29. begin = 0
  30. end = len(s)- 1
  31. while begin < end:
  32. s[begin], s[end] = s[end], s[begin]
  33. begin += 1
  34. end -= 1
  35. return "".join(s)
 
 
  1. 牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事CatFish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
  2. class Solution:
  3. def ReverseSentence(self, s):
  4. # write code here
  5. return " ".join([i[::-1] for i in s.split(" ")])[::-1]
 
 
  1. LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子.....LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J11,Q12,K13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作24),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0
  2. class Solution:
  3. def IsContinuous(self, numbers):
  4. # write code here
  5. if not numbers:
  6. return False
  7. numbers = sorted(numbers)
  8. count_0 = 0
  9. count_blank = 0
  10. for i in range(len(numbers)):
  11. if numbers[i] == 0:
  12. count_0 += 1
  13. elif numbers[i] != 0:
  14. break
  15. for j in range(i, len(numbers)-1):
  16. if numbers[j+1] - numbers[j] != 1:
  17. if numbers[j+1] - numbers[j] == 0:
  18. return False
  19. count_blank += numbers[j+1] - numbers[j]-1
  20. if count_0 >= count_blank:
  21. return True
  22. else:
  23. return False
 
 
  1. 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0n-1)
  2. class Solution:
  3. def LastRemaining_Solution(self, n, m):
  4. # write code here
  5. # 动态规划,寻找规律
  6. if n < 1 or m < 1:
  7. return -1
  8. last = 0
  9. for i in range(2, n+1):
  10. last = (last+m)%i
  11. return last
  12. # 循环链表模拟法
  13. # 依次循环m次,到达则删除该节点,同时判断node.next == node,如果True返回该节点
 
 
  1. 1+2+3+...+n,要求不能使用乘除法、forwhileifelseswitchcase等关键字及条件判断语句(A?B:C)。
  2. class Solution:
  3. def Sum_Solution(self, n):
  4. # write code here
  5. # and 运算,如果n为False, 返回False, 如果True,返回后面的数
  6. return n and (n + self.Sum_Solution(n-1))
 
 
  1. 写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
  2. class Solution:
  3. def Add(self, num1, num2):
  4. # write code here
  5. while True:
  6. res = (num1 ^ num2) & 0xffffffff
  7. carry = ((num1 & num2) << 1) & 0xffffffff
  8. if carry == 0:
  9. return res if res <= 0x7fffffff else ~(res ^ 0xffffffff)
  10. num1 = res
  11. num2 = carry
 
 
  1. 将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0
  2. class Solution:
  3. def StrToInt(self, s):
  4. # write code here
  5. if not s:
  6. return 0
  7. if s[0] == '+':
  8. flag = 1
  9. s = s[1:]
  10. elif s[0] == '-':
  11. flag = 0
  12. s = s[1:]
  13. else:
  14. flag = -1
  15. asc_0 = ord('0')
  16. asc_9 = ord('9')
  17. res = 0
  18. jinwei = 1
  19. for i in range(len(s)-1, -1,-1):
  20. if ord(s[i]) >= asc_0 and ord(s[i]) <= asc_9:
  21. res += (ord(s[i]) - asc_0) * jinwei
  22. jinwei *= 10
  23. else:
  24. return 0
  25. return -res if flag == 0 else res
 
 
  1. 在一个长度为n的数组里的所有数字都在0n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2
  2. class Solution:
  3. # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
  4. # 函数返回True/False
  5. def duplicate(self, numbers, duplication):
  6. # write code here
  7. i = 0
  8. while True:
  9. if i >= len(numbers):
  10. return False
  11. if numbers[i] != i:
  12. if numbers[i] == numbers[numbers[i]]:
  13. duplication[0] = numbers[i]
  14. return True
  15. index = numbers[i]
  16. numbers[i], numbers[index] = numbers[index], numbers[i]
  17. else:
  18. i += 1
 
 
  1. 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。
  2. class Solution:
  3. def multiply(self, A):
  4. # write code here
  5. b = [1]*len(A)
  6. multi = 1
  7. for i in range(1, len(A)):
  8. multi *= A[i-1]
  9. b[i] = multi
  10. multi = 1
  11. for i in range(len(A)-2, -1, -1):
  12. multi *= A[i+1]
  13. b[i] *= multi
  14. return b
 
 
  1. 请实现一个函数用来匹配包括'.''*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a""ab*ac*a"匹配,但是与"aa.a""ab*a"均不匹配
  2. class Solution:
  3. # s, pattern都是字符串
  4. def match(self, s, pattern):
  5. # write code here
  6. # 两个字符串都为空,返回True
  7. if len(s) == 0 and len(pattern) == 0:
  8. return True
  9. if len(s) > 0 and len(pattern) == 0:
  10. return False
  11. # 考虑第二个模式字符串是否为*的情况
  12. if len(pattern) > 1 and pattern[1] == '*':
  13. if len(s) > 0 and (s[0] == pattern[0] or pattern[0] == '.'):
  14. return self.match(s, pattern[2:]) or self.match(s[1:], pattern[2:]) or self.match(s[1:], pattern)
  15. else:
  16. return self.match(s, pattern[2:])
  17. if len(s)>0 and (pattern[0] == '.' or pattern[0] == s[0]):
  18. return self.match(s[1:], pattern[1:])
  19. return False
 
 
  1. 请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416""-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5""12e+4.3"都不是。
  2. class Solution:
  3. # s字符串
  4. def isNumeric(self, s):
  5. # write code here
  6. allow_char = ['+','-','0','1','2','3','4','5','6','7','8','9','e','E','.']
  7. already_action = 0
  8. after_e = 0
  9. count_dot = 0
  10. count_plus_mins = 0
  11. for i in range(len(s)):
  12. if s[i] not in allow_char:
  13. return False
  14. if s[i] in ['+','-'] and i != 0 and after_e == 0:
  15. return False
  16. if s[i] == '.' and after_e == 1:
  17. return False
  18. if s[i] == '.' and after_e == 0:
  19. count_dot += 1
  20. if count_dot > 1:
  21. return False
  22. if s[i] in ['e', 'E'] and after_e == 1:
  23. return False
  24. if s[i] in ['+', '-'] and after_e == 1:
  25. count_plus_mins += 1
  26. if count_plus_mins > 1:
  27. return False
  28. if s[i] in ['e', 'E']:
  29. after_e = 1
  30. if i == len(s)-1:
  31. return False
  32. return True
 
 
  1. 请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
  2. class Solution:
  3. def __init__(self):
  4. self.s=''
  5. self.count_dic = {}
  6. # 返回对应char
  7. def FirstAppearingOnce(self):
  8. # write code here
  9. # 利用hash表存储每个字符出现的次数,时间复杂度为O(n)
  10. for i in range(len(self.s)):
  11. if self.count_dic[self.s[i]] == 1:
  12. return self.s[i]
  13. return '#'
  14. def Insert(self, char):
  15. # write code here
  16. self.s += char
  17. self.count_dic[char] = self.count_dic.get(char,0)+1
 
 
  1. 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null
  2. class Solution:
  3. def EntryNodeOfLoop(self, pHead):
  4. # write code here
  5. if not pHead or not pHead.next:
  6. return None
  7. low = pHead
  8. fast = pHead
  9. while fast:
  10. low = low.next
  11. fast = fast.next.next
  12. if low == fast:
  13. break
  14. if not fast:
  15. return None
  16. low = pHead
  17. while low != fast:
  18. low= low.next
  19. fast = fast.next
  20. return low
 
 
  1. 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
  2. class Solution:
  3. def deleteDuplication(self, pHead):
  4. # write code here
  5. '''
  6. if not pHead or not pHead.next:
  7. return pHead
  8. newHead = ListNode("a")
  9. newHead.next = pHead
  10. pre = newHead
  11. cur = pHead
  12. flag = 0
  13. while cur.next:
  14. if cur.val == cur.next.val:
  15. flag = 1
  16. cur.next = cur.next.next
  17. else:
  18. if flag == 1:
  19. pre.next = cur.next
  20. cur = cur.next
  21. flag = 0
  22. else:
  23. pre = pre.next
  24. cur = cur.next
  25. if flag == 1:
  26. pre.next = cur.next
  27. return newHead.next
  28. '''
  29. # 采用递归的方式删除
  30. if not pHead or not pHead.next:
  31. return pHead
  32. pNext = pHead.next
  33. if pNext.val != pHead.val:
  34. pHead.next = self.deleteDuplication(pHead.next)
  35. else:
  36. while pNext and pNext.val == pHead.val:
  37. pNext = pNext.next
  38. if not pNext:
  39. return None
  40. else:
  41. pHead = self.deleteDuplication(pNext)
  42. return pHead
 
 
  1. 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
  2. class Solution:
  3. def GetNext(self, pNode):
  4. # write code here
  5. if not pNode:
  6. return pNode
  7. if pNode.right:
  8. r_node = pNode.right
  9. while r_node.left:
  10. r_node = r_node.left
  11. return r_node
  12. while pNode.next:
  13. father_node = pNode.next
  14. if father_node.left == pNode:
  15. return father_node
  16. pNode = father_node
 
 
  1. 请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
  2. class Solution:
  3. def isSymmetrical(self, pRoot):
  4. # write code here
  5. return self.judge_symmetry(pRoot, pRoot)
  6. def judge_symmetry(self, pRoot1, pRoot2):
  7. if not pRoot1 and not pRoot2:
  8. return True
  9. if not pRoot1 or not pRoot2:
  10. return False
  11. if pRoot1.val != pRoot2.val:
  12. return False
  13. return self.judge_symmetry(pRoot1.left, pRoot2.right) and self.judge_symmetry(pRoot1.right, pRoot2.left)
 
 
  1. 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
  2. from collections import deque
  3. class Solution:
  4. def Print(self, pRoot):
  5. # write code here
  6. if not pRoot:
  7. return []
  8. res = deque([pRoot])
  9. tmp = []
  10. ret = []
  11. last = pRoot
  12. flag = 1
  13. while res:
  14. node = res.popleft()
  15. tmp.append(node.val)
  16. if node.left:
  17. res.append(node.left)
  18. if node.right:
  19. res.append(node.right)
  20. if node == last:
  21. ret.append(tmp if flag == 1 else tmp[::-1])
  22. tmp = []
  23. flag = -flag
  24. if res:
  25. last = res[-1]
  26. return ret
 
 
  1. 从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
  2. class Solution:
  3. # 返回二维列表[[1,2],[4,5]]
  4. def Print(self, pRoot):
  5. # write code here
  6. if not pRoot:
  7. return []
  8. from collections import deque
  9. q = deque([pRoot])
  10. ret = []
  11. tmp = []
  12. last = pRoot
  13. while q:
  14. node = q.popleft()
  15. tmp.append(node.val)
  16. if node.left:
  17. q.append(node.left)
  18. if node.right:
  19. q.append(node.right)
  20. if node == last:
  21. ret.append(tmp)
  22. tmp = []
  23. if q: last=q[-1]
  24. return ret
 
 
  1. 请实现两个函数,分别用来序列化和反序列化二叉树
  2. class Solution:
  3. flag = -1
  4. def Serialize(self, root):
  5. # write code here
  6. if not root:
  7. return '$'
  8. return str(root.val)+','+self.Serialize(root.left)+','+self.Serialize(root.right)
  9. def Deserialize(self, s):
  10. # write code here
  11. self.flag += 1
  12. l = s.split(',')
  13. if self.flag >= len(s):
  14. return None
  15. root = None
  16. if l[self.flag] != '$':
  17. root = TreeNode(int(l[self.flag]))
  18. root.left = self.Deserialize(s)
  19. root.right = self.Deserialize(s)
  20. return root
 
 
  1. 给定一棵二叉搜索树,请找出其中的第k小的结点。例如, 5372468 中,按结点数值大小顺序第三小结点的值为4
  2. class Solution:
  3. # 返回对应节点TreeNode
  4. def KthNode(self, pRoot, k):
  5. # write code here
  6. if k <= 0 or not pRoot:
  7. return None
  8. buffer = self.find_k_num(pRoot, [])
  9. if len(buffer) < k:
  10. return None
  11. else:
  12. return buffer[k-1]
  13. def find_k_num(self, pRoot, buffer):
  14. if not pRoot:
  15. return buffer
  16. self.find_k_num(pRoot.left, buffer)
  17. buffer.append(pRoot)
  18. self.find_k_num(pRoot.right, buffer)
  19. return buffer
 
 
  1. 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
  2. class Solution:
  3. def __init__(self):
  4. self.data = []
  5. def Insert(self, num):
  6. # write code here
  7. # 采用二分法实现数据的有序插入
  8. if not self.data:
  9. self.data.append(num)
  10. return
  11. pre = 0
  12. back = len(self.data)-1
  13. while pre <= back:
  14. mid = (back+pre)//2
  15. if mid == 0:
  16. if num < self.data[0]:
  17. self.data.insert(0, num)
  18. else:
  19. self.data.insert(1, num)
  20. return
  21. if mid == len(self.data)-1:
  22. if num > self.data[-1]:
  23. self.data.append(num)
  24. else:
  25. self.data.insert(-1, num)
  26. return
  27. if num < self.data[mid]:
  28. back = mid-1
  29. elif num > self.data[mid]:
  30. pre = mid+1
  31. else:
  32. self.data.insert(mid, num)
  33. def GetMedian(self, data):
  34. # write code here
  35. if not self.data:
  36. return
  37. if len(self.data) % 2 == 1:
  38. return self.data[len(self.data)//2]
  39. else:
  40. return (self.data[len(self.data)//2-1] + self.data[len(self.data)//2])/2.0
 
 
  1. 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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]}。
  2. from collections import deque
  3. class Solution:
  4. def maxInWindows(self, num, size):
  5. # write code here
  6. if not num or size > len(num) or size < 1:
  7. return []
  8. res = []
  9. window = deque()
  10. for i in range(size):
  11. while window and num[i] >= num[window[-1]]:
  12. window.pop()
  13. window.append(i)
  14. for i in range(size, len(num)):
  15. res.append(num[window[0]])
  16. while window and num[i] >= num[window[-1]]:
  17. window.pop()
  18. if window and i - window[0] >= size:
  19. window.popleft()
  20. window.append(i)
  21. res.append(num[window[0]])
  22. return res
 
 
  1. 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
  2. class Solution:
  3. def hasPath(self, matrix, rows, cols, path):
  4. # write code here
  5. for i in range(rows):
  6. for j in range(cols):
  7. if matrix[i*cols+j] == path[0]:
  8. if self.find(list(matrix), rows, cols, path[1:], i, j):
  9. return True
  10. return False
  11. def find(self, matrix, rows, cols, path, i, j):
  12. if not path:
  13. return True
  14. matrix[i*cols+j] = '0'
  15. if j+1 < cols and matrix[i*cols+j+1] == path[0]:
  16. return self.find(matrix, rows, cols, path[1:],i,j+1)
  17. elif j-1 >= 0 and matrix[i*cols+j-1] == path[0]:
  18. return self.find(matrix, rows, cols, path[1:],i,j-1)
  19. elif i+1 < rows and matrix[(i+1)*cols+j] == path[0]:
  20. return self.find(matrix, rows, cols, path[1:],i+1,j)
  21. elif i-1 >= 0 and matrix[(i-1)*cols+j] == path[0]:
  22. return self.find(matrix, rows, cols,path[1:],i-1,j)
  23. else:
  24. return False
 
 
  1. 地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
  2. class Solution:
  3. def movingCount(self, threshold, rows, cols):
  4. # write code here
  5. visited = [1] * rows * cols
  6. if threshold < 0:
  7. return 0
  8. return self.get_moving_count(threshold, rows, cols, 0, 0, 1, visited)
  9. def get_moving_count(self, threshold, rows, cols, i, j, count, visited):
  10. visited[i * cols + j] = 0
  11. if j + 1 < cols and visited[i * cols + j + 1] and self.getDigitSum(i, j + 1) <= threshold:
  12. count = self.get_moving_count(threshold, rows, cols, i, j + 1, count+1, visited)
  13. if j - 1 >= 0 and visited[i * cols + j - 1] and self.getDigitSum(i, j - 1) < threshold:
  14. count = self.get_moving_count(threshold, rows, cols, i, j - 1, count+1, visited)
  15. if i + 1 < rows and visited[(i + 1) * cols + j] and self.getDigitSum(i+1, j) <= threshold:
  16. count = self.get_moving_count(threshold, rows, cols, i + 1, j, count+1, visited)
  17. if i - 1 >= 0 and visited[(i - 1) * cols + j] and self.getDigitSum(i-1, j) <= threshold:
  18. count = self.get_moving_count(threshold, rows, cols, i - 1, j, count+1, visited)
  19. return count
  20. def getDigitSum(self,num1, num2):
  21. sum = 0
  22. while num1 > 0:
  23. sum += num1%10
  24. num1 /= 10
  25. while num2 > 0:
  26. sum += num2%10
  27. num2 /= 10
  28. return sum




转载于:https://www.cnblogs.com/sancica/p/11059686.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值