1: 题目描述
给定一棵二叉树的前序(根、左、右)和中序(左、根、右)的打印结果,输出此二叉树按层(从左往右)打印结果。
例如一棵二叉树前序:1 2 4 5 3;中序:4 2 5 1 3。可以构建出下图所示二叉树:
按层打印的结果则为:1 2 3 4 5。
输入
第一行只有一个数字,表示二叉树的节点数n(1<=n<=1000); 第二行由a1,a2,...,an(1<=ai<=1000)组成的整数序列(用空格分隔)—表示前序打印结果; 第三行由b1,b2,...,bn(1<=bi<=1000)组成的整数序列(用空格分隔)—表示中序打印结果。 |
样例输入
5 1 2 4 5 3 4 2 5 1 3 |
输出
c1,c2,...,cn,用空格分隔—表示按层打印的结果。 |
样例输出
1 2 3 4 5 |
输入
第一行只有一个数字,表示二叉树的节点数n(1<=n<=1000); 第二行由a1,a2,...,an(1<=ai<=1000)组成的整数序列(用空格分隔)—表示前序打印结果; 第三行由b1,b2,...,bn(1<=bi<=1000)组成的整数序列(用空格分隔)—表示中序打印结果。 |
样例输入
5 1 2 4 5 3 4 2 5 1 3 |
输出
c1,c2,...,cn,用空格分隔—表示按层打印的结果。 |
样例输出
1 2 3 4 5 |
至于树的层次遍历就不多说了,这是基本功,唯一要注意的就是大家在用到栈,队列这类基本数据结构时,如果有可能,尽量自己写出他们的数据结构,用自己定义的栈和队列,这样使我们对这些基本的数据结构有更深的了解,笔者面试的时候就曾经被要求写一个链栈和循环队列,实现基本的功能;所以平时用Java中定义好的Stack,ArrayDeque,LinkListed等等的同学要多多注意啦,毕竟基础还是最重要的。下面直接上代码吧。
import java.util.Arrays;
import java.util.Scanner;
class linkNode{
public TreeNode val;
public linkNode next;
}
class TreeNode{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val)
{
this.val=val;
}
}
//自定义队列
class Squeue{
TreeNode[] data=new TreeNode[100];
int front;
int rear;
public boolean isEmpty()
{
return front==rear;
}
public void InQueue(TreeNode val) throws Exception
{
if((rear+1)%100==front)
{
throw new Exception("队列已满");
}
else
{
rear=(rear+1)%100;
data[rear]=val;
}
}
public TreeNode EnQueue() throws Exception
{
if(front==rear)
throw new Exception("队列为空");
else
{
front=(front+1)%100;
TreeNode val=data[front];
return val;
}
}
}
class LinkQueue{ //li
public int size;
linkNode front;
linkNode rear;
public LinkQueue()
{
linkNode temp=new linkNode();
front=temp;
rear=temp;
}
public boolean isEmpty()
{
return size==0;
}
public TreeNode EnQueue() throws Exception
{
if(isEmpty()==true)
throw new Exception("队列空");
TreeNode val=front.next.val;
front.next=front.next.next;
if(front.next==null)
{
rear=front;
}
size--;
return val;
}
public void InQueue(TreeNode t)
{
linkNode s=new linkNode();
s.val=t;
rear.next=s;
rear=s;
size++;
}
}
public class DaYinBinaryTree
{
public static TreeNode Recons(TreeNode t, int[] pre, int[] mid)
{
if(pre.length>0)
{
int index=find(mid,pre[0]);
int[] mid1=Arrays.copyOfRange(mid,0,index);
int[] mid2=Arrays.copyOfRange(mid,index+1,mid.length);
int[] pre1=Arrays.copyOfRange(pre,1,index+1) ;
int[] pre2=Arrays.copyOfRange(pre,index+1,pre.length);
t=new TreeNode(pre[0]);
t.left=Recons(t.left,pre1,mid1);
t.right=Recons(t.right,pre2,mid2);
}
return t;
}
public static int find(int[] a, int target)
{
for(int i=0;i q=new ArrayDeque<>();
q.offer(t);
int count=0;
while(q.isEmpty()!=true)
{
TreeNode temp=q.poll();
count++;
if(count==pre.length)
System.out.print(temp.val);
else
System.out.print(temp.val+" ");
if(temp.left!=null)
{
q.offer(temp.left);
}
if(temp.right!=null)
{
q.offer(temp.right);
}
}*/
/* Squeue q=new Squeue();
q.InQueue(t);
int count=0;
while(q.isEmpty()!=true)
{
TreeNode temp=q.EnQueue();
count++;
if(count==pre.length)
System.out.print(temp.val);
else
System.out.print(temp.val+" ");
if(temp.left!=null)
{
q.InQueue(temp.left);
}
if(temp.right!=null)
{
q.InQueue(temp.right);
}
}*/
LinkQueue q=new LinkQueue();
q.InQueue(t);
int count=0;
while(q.isEmpty()!=true)
{
TreeNode temp=q.EnQueue();
count++;
if(count==pre.length)
System.out.print(temp.val);
else
System.out.print(temp.val+" ");
if(temp.left!=null)
{
q.InQueue(temp.left);
}
if(temp.right!=null)
{
q.InQueue(temp.right);
}
}
}
}
2:题目描述
用英文字母a-z来分别表示数值0-25, 形成一个26进制的数值表示法。需要你写一个方法,将用a-z表示的26进制数值的字符串,转化为对应的10进制数值。
输入
输入数据有多组,每组占一行,包含多个a-z之间的字符。
样例输入
ba
bcd
gibbon
goodboy
输出
所对应表示的10进制数。
26
731
74962693
2026285376
分析:这也是一道比较基础的题目啦,可能有些童鞋范围不够用,但是Java里用long肯定没问题的,直接上代码了。。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
*
* 进制转换(2017去哪儿网实习题)
*
*
*/
public class JinZhiZhuanHuan {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
List list=new ArrayList<>();
while(sc.hasNext()){
String s=sc.next();
long sum=0;
for(int i=0;i
PS:关于输入输出的问题,这道题要求输入多行,但没说具体是几行,我们只要写成死循环即可,但是要记得输入一个,就要处理一个,然后存起来,最后统一输出,当然我们在本地运行的时候程序是停不下来的,但是不论是牛客网还是赛码网,oj系统都会自动检查测试的case,在相应的地方做停止,不需要我们操心的。比如牛客网上华为机试题库的一道ip地址分类的题,也是如此。
3:题目描述
有一个单词列表,一个初始单词和一个最终单词,初始单词需要通过单词列表逐步变换到最终单词,求变换所需的最短变换路径长度。
变换规则:每次只能变动1个字母(不可交换位置,如:从abc变成cba属于变动了2个字母),每次变换只能从单词列表中选取。
例如:初始单词hot,最终单词dog,单词列表[got, dot, god, dog, lot, log],最短变换路径为[hot,dot,dog],最短变换路径长度为3。
注:单词列表中包含最终单词,不包含初始单词;列表中每一项单词长度与初始单词、最终单词相同;列表中单词不重复;所有字母均为小写。
输入输入数据有三行,第一行为初始单词;第二行为最终单词;第三行为单词列表,单词和单词之间以空格分割
输出
最短变换路径长度。
hot
dog
got dot god dog lot log
样例输出3
分析:拿到这个题目,大家脑海里都想到了最短路径算法,或者肯定跟图有点小关系的样子;确实如此,只不过,他需要我们将所需要的图构造出来,才能使用我们的最短路径算法,广度优先遍历算法等等去求解;
那这道题该如何构造呢,要构造一张图,首先有顶点集合V,边集合E,顶点的话,相信大家都能找到,就是题目中描述的单词列表,题目中的单词列表有6个单词,那就是6个顶点,但不要忘了这里面不包括初始单词,所以我们也要把他算上,就是7个顶点了;那么在程序中怎么定义它呢,我定义了一个类Vertex,他有两个成员变量,no和name,no代表着是节点的编号,从0开始,按着单词列表里出现的顺序,依次增加就好了,而name就是单词本身啦,这样题目中的单词列表就变成了7个Vertex的对象啦~
有了节点,接下来就是边了,哪些节点之间应该有边相连呢,再仔细读读题目,发现我们每次变动字母的时候,只能变动一个,而且顺序不能交换,比如hot-->dot, 这就是一次变化 ,那么我们就认为hot所对应的节点就和dot所对应的节点之间有一条边,其他的都是如此,这样,我们就能完整的构造一个图了,构造的图如下(画的好丑,看不下去了。。。那两条连接的线不是连在一块的,大家不要看错了,自己布局好节点)。
图构造出来了,接下来就可以用广度优先遍历或者迪杰斯特拉算法求最短路径了。这里图采用的是邻接矩阵的数据结构,在使用广度优先遍历的时候,大家注意,可以在节点类Vertex中再定义一个整型变量pre,用来存放在遍历过程中将其放入队列的前一个节点,初始节点的pre为-1,比如got,dot,lot对应节点的pre都是0,指向hot对应的节点,这样放我们遍历到目标节点,即dog时,往回寻找,知道找到某个节点的pre=-1时,所经过的节点个数即为最短路径了。
上代码:
import java.util.ArrayDeque;
import java.util.Scanner;
/**
*
* 单词变换
*
*
*/
//邻接矩阵表示法
class Vertex{
public int no;
public String name;
public int pre;
public Vertex(int no,String name)
{
this.no=no;
this.name=name;
pre=-1;
}
}
class Graph{
public int edge[][]=new int[100][100];
public int n;
public int e;
public Vertex[] vex=new Vertex[100];
public boolean isBian(Vertex v1,Vertex v2)
{ int count=0;
for(int i=0;i q=new ArrayDeque<>();
//System.out.println(v.name);
visited[0]=true;
q.offer(v);
while(q.isEmpty()!=true)
{
Vertex temp=q.poll();
for(int i=0;i
Ok啦,就先这样吧~~啧啧啧