刷题记录
解题过程
1、102.二叉树的层序遍历
给你二叉树的根节点 root
,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
思路: 层序遍历一个二叉树,就是从左到右一层一层的去遍历二叉树。需要借用一个辅助数据结构即队列来实现二叉树的广度优先遍历。队列先进先出,符合一层一层遍历的逻辑。
深度优先搜索
class Solution {
public List<List<Integer>> res = new ArrayList<List<Integer>>();
public List<List<Integer>> levelOrder(TreeNode root) {
dfs(root, 0);
return res;
}
public void dfs(TreeNode node, int deep) {
if (node == null) {
return;
}
deep++;
if (res.size() < deep) {
List<Integer> item = new ArrayList<Integer>();
res.add(item);
}
res.get(deep - 1).add(node.val);
dfs(node.left, deep);
dfs(node.right, deep);
}
}
广度优先搜索
class Solution {
public List<List<Integer>> res = new ArrayList<List<Integer>>();
public List<List<Integer>> levelOrder(TreeNode root) {
bfs(root);
return res;
}
public void bfs(TreeNode node) {
if (node == null) {
return;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(node);
while (!queue.isEmpty()) {
List<Integer> item = new ArrayList<Integer>();
int len = queue.size();
while (len > 0) {
TreeNode tmp = queue.poll();
item.add(tmp.val);
if (tmp.left != null) {
queue.offer(tmp.left);
}
if (tmp.right != null) {
queue.offer(tmp.right);
}
len--;
}
res.add(item);
}
return;
}
}
2、226.翻转二叉树
给你一棵二叉树的根节点 root
,翻转这棵二叉树,并返回其根节点。
思路: 只要把每一个节点的左右孩子翻转一下,就可以达到整体翻转的效果。这道题目使用前序遍历和后序遍历都可以,唯独中序遍历不方便,因为中序遍历会把某些节点的左右孩子翻转两次!
递归法
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) {
return null;
}
swapChildren(root);
invertTree(root.left);
invertTree(root.right);
return root;
}
public void swapChildren(TreeNode node) {
TreeNode tmp = node.left;
node.left = node.right;
node.right = tmp;
}
}
迭代法
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) {
return null;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while (!queue.isEmpty()) {
int len = queue.size();
while (len > 0) {
TreeNode tmp = queue.poll();
swapChildren(tmp);
if (tmp.left != null) {
queue.offer(tmp.left);
}
if (tmp.right != null) {
queue.offer(tmp.right);
}
len--;
}
}
return root;
}
public void swapChildren(TreeNode node) {
TreeNode tmp = node.left;
node.left = node.right;
node.right = tmp;
}
}
3、101.对称二叉树
给你一个二叉树的根节点 root
, 检查它是否轴对称。
思路: 这里要比较的是根节点的两个子树是否是相互翻转的,进而判断这个树是不是对称树,所以要比较的是两个树,参数也是左子树节点和右子树节点。同样,这里也可以用递归法和迭代法来实现。
递归法
class Solution {
public boolean isSymmetric(TreeNode root) {
return compareNode(root.left, root.right);
}
//递归法
public boolean compareNode(TreeNode left, TreeNode right) {
//比较好判断的情况
if (left == null && right == null) {
return true;
} else if (left == null && right != null) {
return false;
} else if (left != null && right == null) {
return false;
} else if (left.val != right.val) {
return false;
}
//左右节点值相等,继续向下判断
//内侧
boolean inCmp = compareNode(left.right, right.left);
//外侧
boolean outCmp = compareNode(left.left, right.right);
return inCmp && outCmp;
}
}
迭代法
class Solution {
public boolean isSymmetric(TreeNode root) {
//迭代法
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root.left);
queue.offer(root.right);
while (!queue.isEmpty()) {
TreeNode leftNode = queue.poll();
TreeNode rightNode = queue.poll();
if (leftNode == null && rightNode == null) {
continue;
}
if (leftNode == null || rightNode == null || leftNode.val != rightNode.val) {
return false;
}
//外侧入队
queue.offer(leftNode.left);
queue.offer(rightNode.right);
//内侧入队
queue.offer(leftNode.right);
queue.offer(rightNode.left);
}
return true;
}
}
总结
掌握层序遍历这种遍历方式(借助队列),熟练使用递归法和迭代法解决问题。