面试题27. 二叉树的镜像
请完成一个函数,输入一个二叉树,该函数输出它的镜像。
示例 1:
输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]
分析
二叉树的镜像就是通过交换原二叉树中的左右子树变化而来的
因此可以使用递归来做
递归返回条件:当前结点为 NULL
实现操作:交换当前结点的左右子树
class Solution {
public:
TreeNode* mirrorTree(TreeNode* root) {
if (root == NULL) {
return NULL;
}//终止条件
swap(root->left, root->right);//交换
mirrorTree(root->left);//递归交换当前节点的左子树
mirrorTree(root->right);递归交换当前节点的右子树
return root;
}
};
对于swap操作
//下面三句是将当前节点的左右子树交换
TreeNode tmp = root.right;
root.right = root.left;
root.left = tmp;
面试题28. 对称的二叉树
分析
采用递归,
递归结束条件:
- 都为空指针则返回 true
- 只有一个为空则返回 false
递归过程:
- 判断两个指针当前节点值是否相等
- 判断 A 的右子树与 B 的左子树是否对称
- 判断 A 的左子树与 B 的右子树是否对称
短路:
在递归判断过程中存在短路现象,也就是做 与 操作时,如果前面的值返回 false 则后面的不再进行计算
时间复杂度:O(n)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution{
public:
bool isSymmetric(TreeNode* root) {
return ismirror(root,root);
};
bool ismirror(TreeNode *p,TreeNode *q)
{
if(p==NULL && q==NULL)
return true;//先判断true的情况
if(p==NULL || q==NULL)
return false;
if(p->val == q->val)
return(ismirror(p->left,q->right) && ismirror(p->right,q->left));
return false;//如果节点值不相等,返回false;
/*
return (p->val == q->val)
&& ismirror(p->left, q->right)
&& ismirror(p->right, q->left);
*/
}
};
螺旋矩阵
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例 1:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
示例 2:
输入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]
分析:
这里的方法不需要记录已经走过的路径,所以执行用时和内存消耗都相对较小
- 首先设定上下左右边界
- 其次向右移动到最右,此时第一行因为已经使用过了,可以将其从图中删去,体现在代码中就是重新定义上边界
- 判断若重新定义后,上下边界交错,表明螺旋矩阵遍历结束,跳出循环,返回答案
- 若上下边界不交错,则遍历还未结束,接着向下向左向上移动,操作过程与第一,二步同理
- 不断循环以上步骤,直到某两条边界交错,跳出循环,返回答案
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector <int> ans;
if(matrix.empty()) return ans; //若数组为空,直接返回答案
int u = 0; //赋值上下左右边界
int d = matrix.size() - 1;//长度
int l = 0;
int r = matrix[0].size() - 1;//宽度
while(true)
{
for(int i = l; i <= r; ++i) ans.push_back(matrix[u][i]); //向右移动直到最右
if(++ u > d) break; //重新设定上边界,若上边界大于下边界,则遍历遍历完成,下同
for(int i = u; i <= d; ++i) ans.push_back(matrix[i][r]); //向下
if(-- r < l) break; //重新设定右边界
for(int i = r; i >= l; --i) ans.push_back(matrix[d][i]); //向左
if(-- d < u) break; //重新设定下边界
for(int i = d; i >= u; --i) ans.push_back(matrix[i][l]); //向上
if(++ l > r) break; //重新设定左边界
}
return ans;
}
};