题目一:二叉树
要求:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路:
前序序列能确定根节点,用根节点,把中序划分为左右子树
基于递归的思路,重复上述步骤
class TreeNod:
def __init__(self,x):
self.val = x
self.left = None
self.right = None
class Solution:
def reConstructBinaryTree(self, pre ,tin): # pre是前序,tin是中序列表
if (len(pre) == 0):
return None
root = TreeNode(pre[0])
tin_root_index = tin.index(root.val) # 在‘中序’中找到根节点,分为左右
if tin_root_index > 0: # 有左子树
new_pre = pre[1:len(pre)+1] # 注意下标志
new_tin = tin[:tin_root_index]
root.left = self.reConstructeBinaryTree(new_pre,new_tin) # 递归进行
if tin_root_index != len(ten)-1: # 有右子树
new_tin = [tin_root_index+1:]
new_pre = [len(pre)-len(new_tin):]
root.right = self.reConstructBinaryTree(new_pre,new_tin) # 递归进行
return root
题目二:栈和队列
要求:
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
思路:
一个栈处理push,新节点放入该栈,一个栈处理pop,初始为空
当需要pop时,如果pop栈不空,则直接出栈,如果空,则从push栈弹出全部内容放到pop栈,pop栈出栈一个
class Solution:
def __init__(self):
self.push_stack = [] # 实现队列的push
seld.pop_stack = [] # 实现队列的pop
def push(self,node):
self.push_stack.append(node)
def pop(self,node):
if len(self.pop_stack) == 0:
if len(self.pop_stack) == 0:
print ('Nothing')
return None
else:
for i in range(len(self.push_stack),-1,-1):
self.pop_stack.append(self.push_stack[i])
self.push_stack = [] # 这个时候队列要便是为空,因为pop完了
value = self.pop_stack[-1]
self.pop_stack = self.pop_stack[0:-1]
return value # 这个value就是我们要pop的
如果用两个队列来模拟栈呢?
初始两个队列都为空
元素a,b,c入栈,则将a,b,c先加入到q1中吧
此时要弹出c,则将ab依次出队,并加入到q2中,将c删除(弹出)
要弹出b,则将a出队,加入到q1中,将b删除
要入栈d,由于q1不空,则追加到q1后面
以此类推
题目三:旋转数组的最小数字
思路:
很简单,从前往后扫,找到第一个比上一个元素小的元素,就说明是最小元素了
class Solution:
def minNumberInRotateArray(self, rotateArray):
if len(rotateArray) == 0:
return 0
# 这里-1是因为下面代码有i+1
for i in range(0,len(rotateArray)-1):
if rotateArray[i+1] < rotateArray[i]:
return rotateArray[i+1]
# 都没找到
return rotateArray[0]
思路2
整个数组由两个递增有序子数组构成。
两个指针分别指向首尾,按照旋转的规则,第一个元素应当大于或者等于最后一个元素(如果小于,说明数组未做旋转,第一个元素就是最小的)。
找mid中间元素,如果mid属于前一半,则它应该大于或等于head,那么此时可以将head移动到mid处,head仍属于前一个数组,目标位于首尾之间;如果mid属于后一半,则它应该小于或等于rear,此时可将rear移动到mid,rear仍属于后一半,目标位于首尾之间。
这种移动方式,head始终属于前一个数组,rear始终属于后一个数组,当hear和rear相邻的时候,说明到达了交界处,rear指向目标。
def minNumberInRotateArray(self, arr):
if len(rotateArray) == 0:
return 0
head = 0
rear = len(arr) - 1
if arr[head] < arr[rear]:
print(arr[head])
while (head != rear - 1):
mid = (head + rear)//2
if arr[mid] >= arr[head]:
head = mid
continue
if arr[mid] <= arr[rear]:
rear = mid
continue
return arr[rear]
参考:https://codingcat.cn/article/22