五一回来,继续做《剑指offer》,写代码使我快乐T_T
python的很多语法还需要继续熟练,加以理解与掌握
树的子结构
题目描述:
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
class Solution:
def HasSubtree(self, p1, p2):
if p1==None or p2==None:
return False
else:
return self.judge(p1,p2)
#由于递归中如果递归到p2为空树,应该返回True,因此需要重新建立一个递归函数
def judge(self,p1,p2):
if p2==None:#当p2为空,返回true
return True
if p1==None:#当p1为空的时候,p2必须一样为空
return p1==p2
result=False
if p1.val==p2.val:#当p1,p2值一样的时候,开始递归判断p1,p2的左右树
result=self.judge(p1.left,p2.left) and self.judge(p1.right,p2.right)
return result or self.judge(p1.left,p2) or self.judge(p1.right,p2)
#返回result的判断结果,或者在p1的左右树中查找
本质上使用的是递归调用判断函数,但是由于题目要求,空树不是任意一个树的子结构,因此需要将递归调用的函数重新写【递归的最后终止条件是空树认为是相同的】
二叉树的镜像
题目描述:
操作给定的二叉树,将其变换为源二叉树的镜像。
输入描述:
二叉树的镜像定义:源二叉树
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):
# 由于题目要求将源二叉树变化为镜像,因此不能新建一个二叉树
if root==None:
return
root.left,root.right=root.right,root.left#需要在源二叉树上进行操作,交换左右树
self.Mirror(root.left)#递归左树
self.Mirror(root.right)#递归右树
return
在这个题中,递归的终止节点是该根节点为空则返回,递归的时候,先将左右子树根节点对换,然后递归调用镜像函数对左树进行处理,然后递归调用镜像函数对右树进行处理即可。
注意python中可以直接使用语句:
a,b=b,a
来对a,b元素进行对换,效果等同于:
temp=a
a=b
b=temp
顺时针打印矩阵
题目描述:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字
例如,如果输入如下4X4矩阵: 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.
class Solution:
# matrix类型为二维列表,需要返回列表
def printMatrix(self, matrix):
n=len(matrix)
m=len(matrix[0])
ls=[]
up,down,left,right=0,n,0,m#定义好四个边界
while(True):
#分为四个步骤,右下左上,打印的过程中,如果遇到边界重合,表示打印完毕,退出循环
#向右打印,打印完一行,上边界向下移动一个位置
i=up
for j in range(left,right,1):
ls.append(matrix[i][j])
up+=1
if(up==down):
break
#向下打印,打印完一列,右边界向左移动一个位置
j=right-1
for i in range(up,down,1):
ls.append(matrix[i][j])
right-=1
if(right==left):
break
#向左打印,打印完一行,下边界向上移动一个位置
i=down-1
for j in range(right-1,left-1,-1):
ls.append(matrix[i][j])
down-=1
if(up==down):
break
#向上打印,打印完一列,左边界向右移动一个位置
j=left
for i in range(down-1,up-1,-1):
ls.append(matrix[i][j])
left+=1
if(right==left):
break
return ls
打印的过程分解为向右,向下,向左,向上,每次执行完一个步骤,将打印边界进行修改,如果边界下一个步骤的边界重合,表示循环完毕退出即可。
包含min函数的栈
题目描述:
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
class Solution:
def __init__(self):
self.stack=[]
self.minstack=[]#定义存储最小值的辅助堆栈
def push(self, node):
self.stack.append(node)
if not self.minstack:#如果辅助栈没有元素直接将node元素push进去
self.minstack.append(node)
else:#如果有元素,需要比较node元素与辅助栈的顶元素的大小进行push
if node<self.minstack[-1]:#如果追加的元素小于栈顶的元素,辅助堆栈的栈顶push该元素
self.minstack.append(node)
else:#如果追加的元素大于栈顶的元素,辅助堆栈的栈顶push堆栈栈顶的元素
self.minstack.append(self.minstack[-1])
def pop(self):
if self.stack:#辅助堆栈与元素堆栈同时pop
self.minstack.pop()
return self.stack.pop()
else:
return None
def top(self):
return self.stack[-1]
def min(self):
return self.minstack[-1]
本题要求最小元素的查找函数的时间复杂度为O(1),因此不能要将每一次压栈操作后的最小元素储存起来,因此比较好想到的是,使用另一个辅助栈,每次压栈的时候存储当前数组栈的最小元素即可。需要注意pop的时候要同时将数组栈的顶端元素与辅助栈的顶端元素同时pop,调用min函数的使用只要将辅助栈的顶端元素显示出来即可。