《牛客网 剑指Offer20--40道》

牛客网 20到40题

面试题21:栈的压人弹出序列

题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
思路:借用一个辅助的栈,遍历压栈顺序,先讲第一个放入栈中,这里是1,然后判断栈顶元素是不是出栈顺序的第一个元素,这里是4,很显然1≠4,所以我们继续压栈,直到相等以后开始出栈,出栈一个元素,则将出栈顺序向后移动一位,直到不相等,这样循环等压栈顺序遍历完成,如果辅助栈还不为空,说明弹出序列不是该栈的弹出顺序。
遇到的问题:在while出栈循环中,发现当循环出栈到j = 4,data_pushA已空时,还会调用peek(),因此抛出EmptyException()。所以我加上了一句,如果data_pushA为空,break;
在这里插入图片描述
代码:运行时间:17ms 占用内存:9384k

import java.util.ArrayList;
import java.util.Stack;
public class Solution {
   
    public boolean IsPopOrder(int [] pushA,int [] popA) {
   
      if(pushA == null||popA == null) return false;
      if(pushA.length != popA.length) return false;
      Stack data_pushA = new Stack();
      int length = pushA.length;
       int j = 0;
      for(int i = 0;i<length;i++)
      {
   
          data_pushA.push(pushA[i]);
          if((int)data_pushA.peek() == popA[j]) //如果发现栈顶指针等于出栈的序列的某个值
          {
   
              while((int)data_pushA.peek() == popA[j])
              {
   
                  data_pushA.pop();
                  j++;
                  if(data_pushA.isEmpty()) break;
              }
          }
      }
        return data_pushA.isEmpty();
    }
}

面试题22:由上向下打印二叉树 广度优先遍历****

题目:从上往下打印出二叉树的每个节点,同层节点从左至右打印。
思路:使用两个队列一个存放节点,一个存放值。先将根节点加入到队列中,然后遍历队列中的元素,遍历过程中,访问该元素的左右节点,再将左右子节点加入到队列中来。
在这里插入图片描述
遇到的问题:我广度优先遍历新建一个二叉树,利用ArrayList,虽然代码量少,循环的上下界很容易错,调试了1小时。广度优先遍历精髓:一个for循环,i<arrayList.size(),在不断遍历当前结点的时候,如果有左子树,将左子树存入arrayList中,有右子树存入arrayList。循环中每次去TreeNode = arrayList.get(i); i++。巧妙就巧妙在,虽然只用了一个arrayList,但是for()循环遍历整个二叉树,每循环一次,都将当前结点的左右子树(若有)存放到arrayList中,因此arrayList的size()是一个动态增加的过程,arrayList(i++)就是二叉树的每一层从左到右。

public class Task22 {
   
	public TreeNode newTree(int[]array)  //按广度优先新建树
	{
   
		ArrayList<TreeNode> treeNodes = new ArrayList<>();
		TreeNode root = new TreeNode(array[0]);
		treeNodes.add(root);
		for(int i = 0; i< array.length;i++)
		{
   
			TreeNode node = new TreeNode(array[i]);
			treeNodes.add(node);
		}
		
		for(int i = 1; i<= array.length/2;i++)
		{
   
			treeNodes.get(i).left = treeNodes.get(2*i);
			treeNodes.get(i).right = treeNodes.get(2*i+1);
		}
		return treeNodes.get(1);
	}
	 public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
   
	     
	      ArrayList<TreeNode> list = new ArrayList<TreeNode>();
	      ArrayList<Integer> deque = new ArrayList<Integer>();
         if(root == null) 
         {
   
             return deque;
         }
	      list.add(root);
	      for(int i = 0;i<list.size();i++)
	      {
   
	          TreeNode node = list.get(i);
	          if(node.left != null)
	          {
   
	              list.add(node.left);
	          }
	          if(node.right !=  null)
	          {
   
	              list.add(node.right);
	          }
	          deque.add(node.val);
	      }
	        return deque;
	    } 
	 public static void main(String[] args) {
   
		 Task22 task22 = new Task22();
		 int [] array = {
   10,6,14,4,8,12,16};
		 TreeNode root = task22.newTree(array);
		 ArrayList<Integer> deque = task22.PrintFromTopToBottom(root);
		 for(Integer i:deque)
		 System.out.println(i);
	}
}

面试题23:二叉搜索树的后序遍历

题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
思路:注意:需要先知道的:二叉搜索树后序遍历,最右一个为根结点root,左子树值都比root小,右子树值都比root大

代码:能不用递归就尽量不用递归,根据二叉树后序遍历得的结果的特点运行时间:15ms 占用内存:9252k
注意: 一维数组判断是否为空1、array null 判断指针 2、array.length == 0;判断长度是否为空

public class Solution {
   
    public boolean VerifySquenceOfBST(int [] sequence) {
   
        if(sequence == null) return false;
        if(sequence.length == 0) return false;
        if(sequence.length <2) return true;
        int length =  sequence.length - 1;
        int root = 0,i  = 0;
        while(length>=0)
        {
   
            root = sequence[length];
            while(sequence[i]<root) i++;
            while(sequence[i]>root) i++;
            if(i<length -1) return false;
            length --;
            i = 0;
        }
        return true;
    }
}

面试题24:二叉树中和为某一值的路径 ****

题目:输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值