目录
107.二叉树的层序遍历Ⅱ
1.解题思路
1.将每层得到的列表用栈收集,再将栈pop出来用最后的列表收集
2.我的实现
实现遇到的问题
代码
java
public List<List<Integer>> res=new ArrayList<>();
public Stack<List<Integer>> tmpstack=new Stack<>();
public List<List<Integer>> levelOrderBottom(TreeNode root) {
levelOrderfun2(root);
return res;
}
public void levelOrderfun2(TreeNode root){
if (root==null){
return;
}
Queue<TreeNode> queue=new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
List<Integer> tmpres=new ArrayList<>();
int size= queue.size();
while (size>0){
TreeNode tmp=queue.poll();
tmpres.add(tmp.val);
if (tmp.left!=null){
queue.add(tmp.left);
}
if (tmp.right!=null){
queue.add(tmp.right);
}
size--;
}
//用栈收集每个列表,后进先出
tmpstack.push(tmpres);
}
//用列表收集最后结果
while (!tmpstack.isEmpty()){
res.add(tmpstack.pop());
}
}
代码中的错误
3.标准实现
java
public class N0107 {
/**
* 解法:队列,迭代。
* 层序遍历,再翻转数组即可。
*/
public List<List<Integer>> solution1(TreeNode root) {
List<List<Integer>> list = new ArrayList<>();
Deque<TreeNode> que = new LinkedList<>();
if (root == null) {
return list;
}
que.offerLast(root);
while (!que.isEmpty()) {
List<Integer> levelList = new ArrayList<>();
int levelSize = que.size();
for (int i = 0; i < levelSize; i++) {
TreeNode peek = que.peekFirst();
levelList.add(que.pollFirst().val);
if (peek.left != null) {
que.offerLast(peek.left);
}
if (peek.right != null) {
que.offerLast(peek.right);
}
}
list.add(levelList);
}
List<List<Integer>> result = new ArrayList<>();
for (int i = list.size() - 1; i >= 0; i-- ) {
result.add(list.get(i));
}
return result;
}
}
区别
4.题目总结
199.二叉树的右视图
1.解题思路
层序遍历这个二叉树,取每层最后一个元素
定义变量接收时,每一个就要在层循环(一个层里面)里面,每一层就要在层循环外面
2.我的实现
代码
java
public List<Integer> result=new ArrayList<>();
public List<Integer> rightSideView(TreeNode root) {
rightSideViewfunc(root);
return result;
}
public void rightSideViewfunc(TreeNode root){
if (root==null){
return;
}
Queue<TreeNode> queue=new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
//每一层的大小
int size= queue.size();
//遍历每一层的所有节点
while (size>0){
//接收每一个节点
TreeNode tmp=new TreeNode();
//每进来一个就要推出
tmp=queue.poll();
//当为最后一个节点时就收集
if (size==1){
result.add(tmp.val);
}
if (tmp.left!=null){
queue.offer(tmp.left);
}
if (tmp.right!=null){
queue.offer(tmp.right);
}
size--;
}
}
}
3.标准实现
java
public class N0199 {
/**
* 解法:队列,迭代。
* 每次返回每层的最后一个字段即可。
*
* 小优化:每层右孩子先入队。代码略。
*/
public List<Integer> rightSideView(TreeNode root) {
List<Integer> list = new ArrayList<>();
Deque<TreeNode> que = new LinkedList<>();
if (root == null) {
return list;
}
que.offerLast(root);
while (!que.isEmpty()) {
int levelSize = que.size();
for (int i = 0; i < levelSize; i++) {
TreeNode poll = que.pollFirst();
if (poll.left != null) {
que.addLast(poll.left);
}
if (poll.right != null) {
que.addLast(poll.right);
}
if (i == levelSize - 1) {
list.add(poll.val);
}
}
}
return list;
}
}
4.题目总结
637.二叉树的层平均值
1.解题思路
遍历每一层的节点,节点的值用一个double收集,并加入sum中,遍历完一层后求平均并加入最终列表中
2.我的实现
java
public List<Double> averageOfLevels(TreeNode root) {
List<Double> res=new ArrayList<>();
if (root==null){
return null;
}
Queue<TreeNode> queue=new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
//需要算每一层的就放在每一层的层序遍历外面
Double sumdouble=0.0;
int tmpInt;
TreeNode tmpTreeNode=new TreeNode();
int size= queue.size();
int tmpSize=size;
while (tmpSize>0){
tmpTreeNode=queue.poll();
tmpInt=tmpTreeNode.val;
sumdouble+=tmpInt;
if (tmpTreeNode.left!=null){
queue.add(tmpTreeNode.left);
}
if (tmpTreeNode.right!=null){
queue.add(tmpTreeNode.right);
}
tmpSize--;
}
//一层遍历完之后,计算平均数
Double avg=sumdouble/size;
res.add(avg);
}
return res;
}
3.标准实现
java
// 637. 二叉树的层平均值
public class N0637 {
/**
* 解法:队列,迭代。
* 每次返回每层的最后一个字段即可。
*/
public List<Double> averageOfLevels(TreeNode root) {
List<Double> list = new ArrayList<>();
Deque<TreeNode> que = new LinkedList<>();
if (root == null) {
return list;
}
que.offerLast(root);
while (!que.isEmpty()) {
int levelSize = que.size();
double levelSum = 0.0;
for (int i = 0; i < levelSize; i++) {
TreeNode poll = que.pollFirst();
levelSum += poll.val;
if (poll.left != null) {
que.addLast(poll.left);
}
if (poll.right != null) {
que.addLast(poll.right);
}
}
list.add(levelSum / levelSize);
}
return list;
}
}
429.N叉树的层序遍历
1.解题思路
使用层序遍历,用队列遍历每一层,然后弹出每一个,按每层个数弹出
2.我的实现
java
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> result=new ArrayList<>();
if (root==null){
return result;
}
Queue<Node> tmpNodeQueue=new LinkedList<>();
tmpNodeQueue.offer(root);
while (!tmpNodeQueue.isEmpty()){
int size=tmpNodeQueue.size();
List<Integer> tmpList=new ArrayList<>();
Node tmpNode=new Node();
for (int i = 0; i < size; i++) {
tmpNode=tmpNodeQueue.poll();
tmpList.add(tmpNode.val);
//遍历每个节点的孩子节点
//遇到null就停
for (Node x:
tmpNode.children) {
tmpNodeQueue.offer(x);
}
}
result.add(tmpList);
}
return result;
}
3.标准实现
java
public class N0429 {
/**
* 解法1:队列,迭代。
*/
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> list = new ArrayList<>();
Deque<Node> que = new LinkedList<>();
if (root == null) {
return list;
}
que.offerLast(root);
while (!que.isEmpty()) {
int levelSize = que.size();
List<Integer> levelList = new ArrayList<>();
for (int i = 0; i < levelSize; i++) {
Node poll = que.pollFirst();
levelList.add(poll.val);
List<Node> children = poll.children;
if (children == null || children.size() == 0) {
continue;
}
for (Node child : children) {
if (child != null) {
que.offerLast(child);
}
}
}
list.add(levelList);
}
return list;
}
515.在每个树行中找最大值
1.解题思路
遍历每一行二叉树,用一个列表收集,然后返回列表中的最大值,用结果列表收集。
2.我的实现
实现遇到的问题
求列表中的最大值
Collections.max(list)
:这个方法返回列表 list
中的最大元素。它通过自然顺序比较元素(即按照元素的 Comparable
实现来比较),因此适用于任何实现了 Comparable
接口的类型,如 Integer
、String
等。
代码
java
public List<Integer> largestValues(TreeNode root) {
List<Integer> result=new ArrayList<>();
if (root==null){
return result;
}
Queue<TreeNode> tmpTreeNodeQueue=new LinkedList<>();
tmpTreeNodeQueue.offer(root);
while (!tmpTreeNodeQueue.isEmpty()){
List<Integer> tmpList=new ArrayList<>();
int size=tmpTreeNodeQueue.size();
TreeNode tmpTreeNode=new TreeNode();
for (int i = 0; i < size; i++) {
tmpTreeNode=tmpTreeNodeQueue.poll();
tmpList.add(tmpTreeNode.val);
if (tmpTreeNode.left!=null){
tmpTreeNodeQueue.offer(tmpTreeNode.left);
}
if (tmpTreeNode.right!=null){
tmpTreeNodeQueue.offer(tmpTreeNode.right);
}
}
int tmpVal= Collections.max(tmpList);
result.add(tmpVal);
}
return result;
}
3.标准实现
java
class Solution {
public List<Integer> largestValues(TreeNode root) {
if(root == null){
return Collections.emptyList();
}
List<Integer> result = new ArrayList();
Queue<TreeNode> queue = new LinkedList();
queue.offer(root);
while(!queue.isEmpty()){
int max = Integer.MIN_VALUE;
for(int i = queue.size(); i > 0; i--){
TreeNode node = queue.poll();
max = Math.max(max, node.val);
if(node.left != null) queue.offer(node.left);
if(node.right != null) queue.offer(node.right);
}
result.add(max);
}
return result;
}
}
116.填充每个节点的下一个右侧节点指针
1.解题思路
层序遍历每层节点,使每一个节点的next指向右边节点,当i遍历到了size-1位置,就指向null,及每行的最后一个位置。
2.我的实现
java
public Node connect(Node root) {
if (root==null){
return root;
}
Queue<Node> queue=new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
int size=queue.size();
Node tmp;
for (int i = 0; i < size; i++) {
tmp=queue.poll();
if (tmp.left!=null){
queue.offer(tmp.left);
}
if (tmp.right!=null){
queue.offer(tmp.right);
}
//当不为一行最后一个时,指向右边,及queue的下一个,及tmp的下一个
//及现在的queue的第一个
if (i!=size-1){
tmp.next=queue.peek();
}else {
tmp.next=null;
}
}
}
return root;
}
3.标准实现
java
class Solution {
public Node connect(Node root) {
Queue<Node> tmpQueue = new LinkedList<Node>();
if (root != null) tmpQueue.add(root);
while (tmpQueue.size() != 0){
int size = tmpQueue.size();
Node cur = tmpQueue.poll();
if (cur.left != null) tmpQueue.add(cur.left);
if (cur.right != null) tmpQueue.add(cur.right);
for (int index = 1; index < size; index++){
Node next = tmpQueue.poll();
if (next.left != null) tmpQueue.add(next.left);
if (next.right != null) tmpQueue.add(next.right);
cur.next = next;
cur = next;
}
}
return root;
}
}
117.填充每个节点的下一个右侧节点指针Ⅱ
实现方法与上一题一样
104.二叉树的最大深度
1.解题思路
层序遍历,遍历完一层高度加1
2.我的实现
java
public int maxDepth(TreeNode root) {
if (root==null){
return 0;
}
Queue<TreeNode> queue=new LinkedList<>();
queue.offer(root);
int high=0;
while (!queue.isEmpty()){
int size=queue.size();
TreeNode tmp;
for (int i = 0; i < size; i++) {
tmp=queue.poll();
if (tmp.left!=null){
queue.offer(tmp.left);
}
if (tmp.right!=null){
queue.offer(tmp.right);
}
}
high++;
}
return high;
}
3.标准实现
java
class Solution {
public int maxDepth(TreeNode root) {
if (root == null) return 0;
Queue<TreeNode> que = new LinkedList<>();
que.offer(root);
int depth = 0;
while (!que.isEmpty())
{
int len = que.size();
while (len > 0)
{
TreeNode node = que.poll();
if (node.left != null) que.offer(node.left);
if (node.right != null) que.offer(node.right);
len--;
}
depth++;
}
return depth;
}
}
111.二叉树的最小深度
1.解题思路
遍历层节点,当其中一个节点的左右孩子都为空时,break,跳出这次循环,及跳出这行,输出highmin。
2.我的实现
实现遇到的问题
实现过程中有两层循环,而break只能退出一层循环,退出之后还要通过指示器退出第二个循环。
代码
java
public int minDepth(TreeNode root) {
int mHigh=0;
if (root==null){
return mHigh;
}
int cur=0;//指示器,用来跳出第二层循环
Queue<TreeNode> queue=new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
TreeNode tmp;
int size=queue.size();
for (int i = 0; i < size; i++) {
tmp=queue.poll();
if (tmp.left==null&&tmp.right==null){
cur=1;
break;
}
if (tmp.left!=null){
queue.offer(tmp.left);
}
if (tmp.right!=null){
queue.offer(tmp.right);
}
}
mHigh++;
if (cur==1){
break;
}
}
return mHigh;
}
3.标准实现
java
class Solution {
public int minDepth(TreeNode root){
if (root == null) {
return 0;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int depth = 0;
while (!queue.isEmpty()){
int size = queue.size();
depth++;
TreeNode cur = null;
for (int i = 0; i < size; i++) {
cur = queue.poll();
//如果当前节点的左右孩子都为空,直接返回最小深度
if (cur.left == null && cur.right == null){
return depth;
}
if (cur.left != null) queue.offer(cur.left);
if (cur.right != null) queue.offer(cur.right);
}
}
return depth;
}
}
区别
如果当前节点的左右孩子都为空,直接返回最小深度