19、树的子结构
思路:对于两棵二叉树来说,要判断B是不是A的子结构,首先第一步在树A中查找与B根节点的值一样的节点。通常对于查找树中某一个节点,我们都是采用递归的方法来遍历整棵树。第二步就是判断树A中以R为根节点的子树是不是和树B具有相同的结构。这里同样利用到了递归的方法,如果节点R的值和树的根节点不相同,则以R为根节点的子树和树B肯定不具有相同的节点;如果它们值是相同的,则递归的判断各自的左右节点的值是不是相同。递归的终止条件是我们达到了树A或者树B的叶节点。
# -*- 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.DoesTree1haveTree2(pRoot1, pRoot2) if not result: result = self.HasSubtree(pRoot1.left, pRoot2) if not result: result = self.HasSubtree(pRoot1.right, pRoot2) return result # 用于递归判断树的每个节点是否相同 # 需要注意的地方是: 前两个if语句不可以颠倒顺序 # 如果颠倒顺序, 会先判断pRoot1是否为None, 其实这个时候pRoot2的结点已经遍历完成确定相等了, 但是返回了False, 判断错误 def DoesTree1haveTree2(self, pRoot1, pRoot2): if pRoot2 == None: return True if pRoot1 == None: return False if pRoot1.val != pRoot2.val: return False return self.DoesTree1haveTree2(pRoot1.left, pRoot2.left) and self.DoesTree1haveTree2(pRoot1.right, pRoot2.right)
20、二叉树的镜像
输入描述:
二叉树的镜像定义:源二叉树 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 False if root.left==None and root.right==None: return False else: root.left,root.right = root.right,root.left if root.left: self.Mirror(root.left) if root.right: self.Mirror(root.right)
/* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } };*/ class Solution { public: void Mirror(TreeNode *pRoot) { if(pRoot==NULL) return; stack<TreeNode*> stackNode; stackNode.push(pRoot); while(stackNode.size()){ TreeNode* tree=stackNode.top(); stackNode.pop(); if(tree->left!=NULL || tree->right!=NULL){ TreeNode *ptemp=tree->left; tree->left=tree->right; tree->right=ptemp; } if(tree->left) stackNode.push(tree->left); if(tree->right) stackNode.push(tree->right); } } };
参考代码地址(https://www.nowcoder.com/profile/6927081/codeBookDetail?submissionId=12712193)
21、顺时针打印矩阵
思路:顺时针打印就是按圈数循环打印,一圈包含两行或者两列,在打印的时候会出现某一圈中只包含一行,要判断从左向右打印和从右向左打印的时候是否会出现重复打印,同样只包含一列时,要判断从上向下打印和从下向上打印的时候是否会出现重复打印的情况。
# -*- coding:utf-8 -*- class Solution: # matrix类型为二维列表,需要返回列表 def printMatrix(self, matrix): # write code here if not matrix: return None res=[] n=len(matrix) #得到矩阵行数 m=len(matrix[0]) #得到矩阵列数 if n==1 and m==1: res=[matrix[0][0]] return res for o in xrange((min(m,n)+1)//2): # //是取整除,9//2为4 [res.append(matrix[o][i]) for i in xrange(o,m-o)] [res.append(matrix[j][m-1-o]) for j in xrange(o,n-o) if matrix[j][m-1-o] not in res] [res.append(matrix[n-1-o][k]) for k in xrange(m-1-o,o-1,-1) if matrix[n-1-o][k] not in res] [res.append(matrix[l][o]) for l in xrange(n-1-o,o-1,-1) if matrix[l][o] not in res] return res
class Solution { public: vector<int> printMatrix(vector<vector<int> > matrix) { vector<int>res; res.clear(); int row=matrix.size();//行数 int collor=matrix[0].size();//列数 //计算打印的圈数 int circle=((row<collor?row:collor)-1)/2+1;//圈数 for(int i=0;i<circle;i++){ //从左向右打印 for(int j=i;j<collor-i;j++) res.push_back(matrix[i][j]); //从上往下的每一列数据 for(int k=i+1;k<row-i;k++) res.push_back(matrix[k][collor-1-i]); //判断是否会重复打印(从右向左的每行数据) for(int m=collor-i-2;(m>=i)&&(row-i-1!=i);m--) res.push_back(matrix[row-i-1][m]); //判断是否会重复打印(从下往上的每一列数据) for(int n=row-i-2;(n>i)&&(collor-i-1!=i);n--) res.push_back(matrix[n][i]);} return res; } };
参考代码地址(https://www.nowcoder.com/profile/2235013/codeBookDetail?submissionId=12595600)
22、包含min函数的栈
# -*- coding:utf-8 -*- class Solution: def __init__(self): self.stack = [] self.min_stack = [] def push(self, node): # write code here self.stack.append(node) if not self.min_stack or node <= self.min_stack[-1]: self.min_stack.append(node) def pop(self): # write code here if self.stack[-1] == self.min_stack[-1]: self.min_stack.pop() self.stack.pop() def top(self): # write code here return self.stack[-1] def min(self): # write code here return self.min_stack[-1]参考代码地址( https://www.nowcoder.com/profile/589201/codeBookDetail?submissionId=558366)
23、栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
思路:借用一个辅助的栈,遍历压栈顺序,先讲第一个放入栈中,这里是1,然后判断栈顶元素是不是出栈顺序的第一个元素,这里是4,很显然1≠4,所以我们继续压栈,直到相等以后开始出栈,出栈一个元素,则将出栈顺序向后移动一位,直到不相等,这样循环等压栈顺序遍历完成,如果辅助栈还不为空,说明弹出序列不是该栈的弹出顺序。
举例:
入栈1,2,3,4,5
出栈4,5,3,2,1
首先1入辅助栈,此时栈顶1≠4,继续入栈2
此时栈顶2≠4,继续入栈3
此时栈顶3≠4,继续入栈4
此时栈顶4=4,出栈4,弹出序列向后一位,此时为5,,辅助栈里面是1,2,3
此时栈顶3≠5,继续入栈5
此时栈顶5=5,出栈5,弹出序列向后一位,此时为3,,辅助栈里面是1,2,3
….
# -*- coding:utf-8 -*- class Solution: def IsPopOrder(self, pushV, popV): # write code here if not pushV or len(pushV) != len(popV): return False stack = [] for i in pushV: stack.append(i) while len(stack) and stack[-1] == popV[0]: stack.pop() popV.pop(0) if len(stack): return False return True
24、从上往下打印二叉树
# -*- coding:utf-8 -*- # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution: # 返回从上到下每个节点值列表,例:[1,2,3] def PrintFromTopToBottom(self, root): # write code here res = [] if root == None: return [] temp =[root] while len(temp): t=temp.pop(0) res.append(t.val) if t.left: temp.append(t.left) if t.right: temp.append(t.right) return res