刷题日记12
今天的主题是二叉树的层序遍历,各个题目的解法大同小异
102. 二叉树的层序遍历
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new LinkedList<>();
if(root == null) return res;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while(!q.isEmpty()){
List<Integer> list = new LinkedList<>();
int len = q.size();
while(len-- > 0){
TreeNode node = q.poll();
list.add(node.val);
if(node.left != null) q.offer(node.left);
if(node.right != null) q.offer(node.right);
}
res.add(list);
}
return res;
}
}
107. 二叉树的层序遍历 II
这道题要求从叶子节点,从下至上进行层序遍历,具体思路是在res链表添加元素时,在头部添加即可。
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> res = new LinkedList<>();
Queue<TreeNode> q = new LinkedList<>();
if(root == null) return res;
q.offer(root);
while(!q.isEmpty()){
List<Integer> list = new LinkedList<>();
int len = q.size();
while(len-- > 0){
TreeNode node = q.poll();
list.add(node.val);
if(node.left != null) q.offer(node.left);
if(node.right != null) q.offer(node.right);
}
res.add(0, list);
}
return res;
}
}
199. 二叉树的右视图
依然是层序遍历,每一层只获取最后一个元素即可。值得注意的是,向队列添加元素时,要先添加left再添加right,因为队列先进先出,这样最后弹出的就是最右边的元素。
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> res = new LinkedList<>();
Queue<TreeNode> q = new LinkedList<>();
if(root == null) return res;
q.offer(root);
while(!q.isEmpty()){
int len = q.size();
int ans = 0;
while(len-- > 0){
TreeNode node = q.poll();
ans = node.val;
if(node.left != null) q.offer(node.left);
if(node.right != null) q.offer(node.right);
}
res.add(ans);
}
return res;
}
}
637. 二叉树的层平均值
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
List<Double> res = new LinkedList<>();
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while(!q.isEmpty()){
int len = q.size();
int l = len;
double ans = 0.0;
while(len-- > 0){
TreeNode node = q.poll();
ans += node.val;
if(node.left != null) q.offer(node.left);
if(node.right != null) q.offer(node.right);
}
res.add(ans / l);
}
return res;
}
}
429. N 叉树的层序遍历
class Solution {
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> res = new LinkedList<>();
Queue<Node> q = new LinkedList<>();
if(root == null) return res;
q.offer(root);
while(!q.isEmpty()){
int len = q.size();
List<Integer> list = new LinkedList<>();
while(len-- > 0){
Node node = q.poll();
list.add(node.val);
if(node.children != null) {
for(Node n : node.children){
q.offer(n);
}
}
}
res.add(list);
}
return res;
}
}
515. 在每个树行中找最大值
class Solution {
public List<Integer> largestValues(TreeNode root) {
List<Integer> res = new LinkedList<>();
Queue<TreeNode> q = new LinkedList<>();
if(root == null) return res;
q.offer(root);
while(!q.isEmpty()){
int len = q.size();
int min = Integer.MIN_VALUE;
while(len-- > 0){
TreeNode node = q.poll();
min = Math.max(min, node.val);
if(node.left != null) q.offer(node.left);
if(node.right != null) q.offer(node.right);
}
res.add(min);
}
return res;
}
}
116. 填充每个节点的下一个右侧节点指针
class Solution {
public Node connect(Node root) {
if(root == null) return root;
Node cur = root;
Queue<Node> q = new LinkedList<>();
q.offer(root);
while(!q.isEmpty()){
int len = q.size();
Stack<Node> s= new Stack<>();
while(len-- > 0){
Node node = q.poll();
if(node.left != null) q.offer(node.left);
if(node.right != null) q.offer(node.right);
if(!s.isEmpty()){
Node n = s.peek();
n.next = node;
}
s.push(node);
}
}
return root;
}
}
104. 二叉树的最大深度
class Solution {
public int maxDepth(TreeNode root) {
if(root == null) return 0;
Queue<TreeNode> q = new LinkedList<>();
int depth = 0;
q.offer(root);
while(!q.isEmpty()){
int len = q.size();
while(len-- > 0){
TreeNode node = q.poll();
if(node.left != null) q.offer(node.left);
if(node.right != null) q.offer(node.right);
}
depth++;
}
return depth;
}
}
111. 二叉树的最小深度
class Solution {
public int minDepth(TreeNode root) {
if(root == null) return 0;
int depth = 0;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while(!q.isEmpty()){
depth++;
int len = q.size();
while(len-- > 0){
TreeNode node = q.poll();
if(node.left != null) q.offer(node.left);
if(node.right != null) q.offer(node.right);
if(node.left == null && node.right == null){
return depth;
}
}
}
return depth;
}
}
226. 翻转二叉树
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return root;
TreeNode cur = root;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while(!q.isEmpty()){
int len = q.size();
while(len-- > 0){
TreeNode node = q.poll();
if(node.left != null) q.offer(node.left);
if(node.right != null) q.offer(node.right);
if(node.left != null || node.right != null){
TreeNode temp = node.left;
node.left = node.right;
node.right = temp;
}
}
}
return root;
}
}
101. 对称二叉树
这道题的思路比较简单,但我一开始没想到。可以用两个指针q,p来遍历左子树和右子树。如果是完全对称的二叉树,其左子树应该和右子树相同。
class Solution {
public boolean isSymmetric(TreeNode root) {
return check(root, root);
}
public boolean check(TreeNode q, TreeNode p){
if(q == null && p == null) return true;
if(q == null || p == null) return false;
return q.val == p.val && check(q.left, p.right) && check(q.right, p.left);
}
}