Java训练题15

一、选择题

1、一棵有15个节点的完全二叉树和一棵同样有15个节点的普通二叉树,叶子节点的个数最多会差多少个?(C)
A. 3
B. 5
C. 7
D. 9
答案解析:C
根据满二叉树的计算公式:20+21+…+2^(n-1)
有15个结点的完全二叉树总共有4层,第四层是叶子结点,总共有8个叶子结点;
有15个结点的普通二叉树最少有1个叶子结点(单边二叉树),所以差值为7;
2、在一棵二叉树中,假定每个结点只有左孩子,没有右孩子,对它分别进行前序遍历和后序遍历,则具有相同的遍历结果。(B )
A. 正确
B. 错误
答案解析:B
前序遍历是先访问根节点,再访问左子树,最后访问右子树;
后序遍历是先访问左子树,再访问右子树,最后才访问根节点;
根据题意设一棵二叉树只有两个结点,根节点为A,左子树为B,前序遍历为AB,后序遍历为BA,所以这句话错误
3、一棵满二叉树同时又是一棵平衡树。这种说法(A )
A. 正确
B. 错误
答案解析:A
平衡二叉树性质:左子树和右子树都是平衡二叉树;每一个节点的左右子树高度差的绝地值 <= 1
满二叉树每一个结点的高度差都为0,所以满二叉树是平衡二叉树
4、已知一棵二叉树的先序和中序遍历序列如下:先序:A、B、C、D、E、F、G、H、I,J中序:C、B、A、E、F、D、I、H、J、G其后序遍历序列为(E )
A. C、B、D、E、A、G、I、H、J、F
B. C、B、D、A、E、G、I、H、J、F
C. C、E、D、B、I、J、H、G、F、A
D. C、E、D、B、I、H、J、G、F、A
E. C、B、F、E、I、J、H、G、D、A
答案解析:E
后序遍历是先左子树,后右子树,最后根节点
由先序遍历知道,A是根节点,排除 A B选项
由中序遍历知道,A的左子树只有两个结点C,B,排除C D 选项;
5、完全二叉树中的叶子结点只可能在最后两层中出现 (A )
A. 正确
B. 错误
答案解析:A
完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中
编号从1至n的结点一一对应时称之为完全二叉树。
所以叶子节点只能出现在最后两层,不然就不符合完全二叉树的定义的。

二、编程题

1、最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。
OJ链接

输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]
输出:
[null,null,null,null,-3,null,0,-2]
解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.

【解题思路】:
对于栈来说,如果一个元素 a 在入栈时,栈里有其它的元素 b, c, d,那么无论这个栈在之后经历了什么操作,只要 a在栈中,b, c, d 就一定在栈中,因为在 a 被弹出之前,b, c, d 不会被弹出。因此,在操作过程中的任意一个时刻,只要栈顶的元素是 a,那么我们就可以确定栈里面现在的元素一定是 a, b, c, d。那么,我们可以在每个元素 a 入栈时把当前栈的最小值 m 存储起来。在这之后无论何时,如果栈顶元素是 a,我们就可以直接返回存储的最小值 m。

class MinStack {
    private Stack<Integer> stack;
    private Stack<Integer> minstack;

    public MinStack() {
        stack=new Stack<>();
         minstack=new Stack<>();
    }
    
    public void push(int val) {
           stack.push(val);
           if(!minstack.empty()){
               int top=minstack.peek();
               //比较小于等于放进去
               if(val<=top){
                   minstack.push(val);
               }
           }else{
               minstack.push(val);
           }
    }
    
    public void pop() {
         int popval=stack.pop();
         if(!minstack.empty()){
             int top=minstack.peek();
             if(top==popval){
                 minstack.pop();
             }
         }
    }
    
    public int top() {
          return stack.peek();
    }
    
    public int getMin() {
          return minstack.peek();
    }
}

2、有效的括号
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
    OJ链接
示例1:
输入:s = "()"
输出:true
示例2:
输入:s = "()[]{}"
输出:true
示例3:
输入:s = "([)]"
输出:false

【解题思路】:
碰到左括号就入栈,碰到右括号就出栈顶元素查看是否匹配,有一个反例返回false;最终遍历结束栈不为空返回false,否则返回true。

class Solution {
    public boolean isValid(String s) {
     Stack<Character> stack = new Stack<>();

        for(int i = 0; i < s.length();i++) {
            char ch = s.charAt(i);
            if(ch == '(' || ch == '[' || ch == '{') {
                //如果是左括号 直接入栈
                stack.push(ch);
            }else{
                //遇到了右括号
                if(stack.empty()) {
                    //右括号多
                    return false;
                }
                char top = stack.peek();//哪个左括号
                if(top == '{' && ch == '}' || top == '[' && ch == ']' || top == '(' && ch == ')') {
                    stack.pop();
                }else{
                    //左右括号不匹配
                    return false;
                }
            }
        }
        if(!stack.empty()) {
            //左括号多
            return false;
        }
        return true;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值