【算法入门级训练】 - DAY10

二叉树篇



前言

本次算法入门训练主要训练以下三个内容:

  1. 以特殊数据结构为载体的算法结构,比如:数组、链表、栈、二叉树等
  2. 以考察常见算法思想基础的算法题,比如:动态规划、贪心、回溯等
  3. 基于某种场景包装下的1和2

提示:以下是本篇文章正文内容

内容

第一题:按之字形顺序打印二叉树

解题思路:还是层序遍历的思想不过就是要控制方向,大家可以用各种方法控制,比如还是层序遍历但是再加入到最后结果集中时根据方向进行reverse。不过为了熟悉数据结构,我用栈和队列辅助实现,核心是栈队列只是辅助,也可以只用队列不过要随时调整方向。核心思路能就是当前层从左向右遍历,那么下一层就是left->right入栈,当前层从右向左遍历,那么下一层就是right->left。
OJ链接:第一题

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>();
        if(root == null){
            return result;
        }
        //用一个栈和队列来实现
        Stack<TreeNode> st = new Stack<>();
        Queue<TreeNode> que = new LinkedList<>();
        int dir = 1; //用来代表打印方向 1: left->right 2:right->left;
        ArrayList<Integer> list = new ArrayList<>();
        st.push(root);
        while(!st.empty()){
            //核心:当前层的打印顺序就表示下一层的入栈顺序
            while(!st.empty()){
                //因为栈天然就是逆序,所以我们只需要控制入栈顺序就行
                TreeNode curr = st.pop();
                list.add(curr.val);
                TreeNode first = (dir == 1) ? curr.left : curr.right;
                TreeNode second = (dir == 1 ) ? curr.right : curr.left;
                //不能直接入栈,因为栈还要出元素,所以用队列暂存
                if(first != null){
                    que.offer(first);
                }
                if(second != null){
                    que.offer(second);
                }
            }
            //一层走完了
            result.add(new ArrayList(list));
            //入下一层的元素进栈
            while(!que.isEmpty()){
                st.push(que.poll());
            }
            list.clear();
            //改变方向
            dir = (dir == 1) ? 2 : 1;
        }
        return result;
    }
}

第二题:二叉搜索树的第k个节点

解题思路:这题有两种思路,1.直接利用递归很简单,2.可以利用BST的特性用循环中序遍历来写。
OJ链接:第二题

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
//方法2:
    public int KthNode (TreeNode proot, int k) {
        //循环中序遍历
        if(proot == null || k <= 0){
                return -1;
        }
        Stack<TreeNode> st = new Stack<>();
        TreeNode node = proot;
        do{
            //把左子树全部入栈
            while(node != null){
                st.push(node);
                node = node.left;
            }
            if(!st.empty()){
                node = st.pop();
                k--;
                if(k == 0){
                    //找到第k个节点
                    return node.val;
                }
                node = node.right;
            }
        }while(node != null || !st.empty());
        return -1;
    }
    //方法1: 
     private void KthNodeHelper(TreeNode proot,int[] k,int[] ret){
         if(proot == null){
             return;
         }
         KthNodeHelper(proot.left,k,ret);
         k[0]--;
         if(k[0] == 0){
             ret[0] = proot.val;
             return;
         }
         KthNodeHelper(proot.right,k,ret);
     }
    public int KthNode (TreeNode proot, int k) {
        if(proot == null || k <= 0){
            return -1;
        }
        //先用递归做一下
        int[] ret = new int[1];
        ret[0] = -1;
        int[] tmp = new int[]{k};
        KthNodeHelper(proot,tmp,ret);
        return ret[0];
    }
}

总结

以上就是今天训练的内容,这两题我觉得还是比较难理解的,代码考虑的也比较多,写完代码了还要跟着自己的思路多走几遍,最好跟着思路画下图特别是第一题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值