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<a.length;i++)
{
if(a[i]==target)
{
return i;
}
}
return -1;
}
public static void main(String[] args) throws Exception
{
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int[] pre=new int[n];
int[] mid=new int[n];
for(int i=0;i<n;i++)
{
pre[i]=sc.nextInt();
}
for(int i=0;i<n;i++)
{
mid[i]=sc.nextInt();
}
TreeNode t=null;
t=Recons(t,pre,mid);
/* ArrayDeque<TreeNode> 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<Long> list=new ArrayList<>();
while(sc.hasNext()){
String s=sc.next();
long sum=0;
for(int i=0;i<s.length();i++)
{
sum=sum+(long)((s.charAt(i)-'a')*Math.pow(26,s.length()-i-1));
}
list.add(sum);
}
for(int i=0;i<list.size();i++)
{
System.out.println(list.get(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<v1.name.length();i++)
{
if(v1.name.charAt(i)!=v2.name.charAt(i))
{
count++;
}
}
if(count==1)
return true;
else
return false;
}
public int find(String d)
{
for(int i=0;i<n;i++)
{
if(vex[i].name.equals(d))
return i;
}
return -1;
}
public int createGraph(Scanner sc)
{
String s=sc.next();
String d=sc.next();
sc.nextLine();
String s1=sc.nextLine();
String list=s+" "+s1;
String[] word=list.split(" ");
for(int i=0;i<word.length;i++)
{
vex[i]=new Vertex(i,word[i]);
n++;
}
for(int i=0;i<word.length;i++)
for(int j=0;j<word.length;j++)
{
if(isBian(vex[i],vex[j]))
{
edge[i][j]=1;
e++;
}
else
{
edge[i][j]=100;
}
}
e=e/2;
int index=find(d);
return index;
}
}
public class DanCiBianHuan {
// 广度遍历求最短路径
public static int BFS(Graph g,Vertex v,Vertex v1)
{
boolean[] visited=new boolean[g.n];
for(int i=0;i<visited.length;i++)
visited[i]=false;
ArrayDeque<Vertex> 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<g.n;i++)
{
if(g.edge[temp.no][i]==1&&!visited[i])
{
visited[i]=true;
// System.out.println(g.vex[i].name);
g.vex[i].pre=temp.no;
if(g.vex[i].name.equals(v1.name))
{ int count=1;
while(g.vex[i].pre!=-1)
{
count++;
i=g.vex[i].pre;
}
return count;
}
q.offer(g.vex[i]);
}
}
}
return -1;
}
//迪杰斯特拉算法求最短路径
public static void Dijkstra(Graph g, Vertex v,Vertex v1,int dist[],int path[])
{ //初始化操作
int[] set=new int[g.n];
int u=0;
for(int i=0;i<g.n;i++)
{
dist[i]=g.edge[v.no][i];
set[i]=0;
if(g.edge[v.no][i]<100)
{
path[i]=v.no;
}else
{
path[i]=-1;
}
}
set[v.no]=1;path[v.no]=-1;//初始化结束
for(int i=0;i<g.n;i++)
{
int min=100;
for(int j=0;j<g.n;j++)
{
if(set[j]==0&&dist[j]<min)
{
u=j;
min=dist[j];
}
}
set[u]=1;
for(int j=0;j<g.n;j++)
{
if(set[j]==0&&dist[u]+g.edge[u][j]<dist[j])
{
dist[j]=dist[u]+g.edge[u][j];
path[j]=u;
}
}
}
System.out.println(dist[v1.no]+1);
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
Graph g=new Graph();
int index=g.createGraph(sc);
Vertex v=g.vex[0];
Vertex v1=g.vex[index];
int[] dist=new int[g.n];
int[] path=new int[g.n];
Dijkstra(g,v,v1,dist,path);
// System.out.println(BFS(g,v,v1));
/* for(int i=0;i<g.n;i++)
{ for(int j=0;j<g.n;j++)
System.out.print(g.edge[i][j]+" ");
System.out.println();
} */
}
}
}
Ok啦,就先这样吧~~啧啧啧