Google模拟面试【面试】
2023-12-25 16:00:42
Google代码面试
Prompt #1
给一个二叉树,定义深度为结点到根;所要遍历的边的数量。
示例二叉树中8的深度为3,1的深度为0。
编写函数返回这个二叉树的所有结点的深度和。
示例二叉树答案是16
1/ \2 3/ \ / \4 5 6 7/ \8 9
public class Main {static class Node{int val;Node left;Node right;public Node(int v){val=v;}}public static void main(String[] args) {Node a=new Node(1);Node b=new Node(2);Node c=new Node(3);Node d=new Node(4);Node e=new Node(5);Node f=new Node(6);Node g=new Node(7);Node h=new Node(8);Node i=new Node(9);a.left=b;a.right=c;b.left=d;b.right=e;c.left=f;c.right=g;d.left=h;d.right=i;int res1=solve1(a);System.out.println(res1);//16}public static int solve1(Node root){sum=0;sumDepths(root,0);return sum;}static int sum;public static void sumDepths(Node root,int depth){sum+=depth;if(root.left!=null){sumDepths(root.left,depth+1);}if(root.right!=null){sumDepths(root.right,depth+1);}}}
Prompt #2
返回每一个结点的子树深度的和,求和
示例二叉树答案是26
树型dp
对于结点x,有两个孩子,y,z
x子树结点个数=1+y的子树结点个数+z的子树结点个数
x子树深度和=(y的子树结点个数+y的子树深度和)+(z的子树结点个数+z的子树深度和)
因为对于孩子y的每个结点来说,其对于y的双亲x的深度都是加了x->y的一条边。
特殊:叶子结点(1,0)
过程分析
8,9,5,6,7:(1,0)
4,3:(3,2)
2:(5,6)
1:(9,16)
2+2+6+16=26
public static int solve2(Node root) {ans=0;dfs(root);return ans;}static class Info{int numNodes;int sumDepths;public Info(int a,int b){numNodes=a;sumDepths=b;}}static int ans;static Info dfs(Node root){Info pInfo=new Info(1,0);if(root.left!=null){Info cInfo=dfs(root.left);pInfo.sumDepths+=cInfo.sumDepths+cInfo.numNodes;pInfo.numNodes+=cInfo.numNodes;}if(root.right!=null){Info cInfo=dfs(root.right);pInfo.sumDepths+=cInfo.sumDepths+cInfo.numNodes;pInfo.numNodes+=cInfo.numNodes;}ans+= pInfo.sumDepths;return pInfo;}
Prompt #3
求出所有节点到目标结点的深度和
比如到4的深度和是18
1/ \2 3/ \ / \4 5 6 7/ \8 9
分析可以得出
到一个目标结点的深度和=
到根结点的目标和-子树中的结点数量+其他结点数量(子树之外的结点数)
其他结点数量=总结点数量-子树结点数量
dfs1把每个子树及其对应的结点数存入到map中
运行结果
<Node1,9>,<Node2,5>,<Node3,3>,<Node4,3>
<Node5,1>,<Node6,1>,<Node7,1>,<Node8,1>,<Node9,1>,
n=root.numNodes=9
sumDists=root.sumDepth=16
模拟运行,忽略其他结点
dfs2(1,16,4)
左分支:newDists=16-5+(9-5)=15
dfs2(2,15,4)
右分支:newDists=15-3+(9-3)=18
dfs(4,18,4)
ans=18
会继续遍历所有结点,但是答案只会保存一个
//视频中把每个子树的结点数信息放到结点中//我把其放到哈希表中static HashMap<Node,Integer> map;//总结点个数static int n;static int solve3(Node root,Node target){ans=0;map=new HashMap<>();sumDists(root,target);return ans;}//把每个子树的结点数放到对应结点和结点数的map中static Info dfs1(Node root){Info pInfo=new Info(1,0);if(root.left!=null){Info cInfo=dfs1(root.left);pInfo.sumDepths+=cInfo.sumDepths+cInfo.numNodes;pInfo.numNodes+=cInfo.numNodes;}if(root.right!=null){Info cInfo=dfs1(root.right);pInfo.sumDepths+=cInfo.sumDepths+cInfo.numNodes;pInfo.numNodes+=cInfo.numNodes;}//和dfs的区别只有此处map.put(root, pInfo.numNodes);return pInfo;}static void dfs2(Node u,int sumDists,Node target){if(u==target){ans=sumDists;}if(u.left!=null){int newSumDists=sumDists-map.get(u.left)+(n-map.get(u.left));dfs2(u.left,newSumDists,target);}if(u.right!=null){int newSumDists=sumDists-map.get(u.right)+(n-map.get(u.right));dfs2(u.right,newSumDists,target);}}static int sumDists(Node root,Node target){Info info=dfs1(root);n=info.numNodes;dfs2(root,info.sumDepths,target);return ans;}
补充 #3用图来解决
到4的深度和为18
1/ \2 3/ \ / \4 5 6 7/ \8 9
2,8,9到4的深度都是1
1,5到4的深度都是2
3到4的深度是3
6,7到4的深度都是4
1*3+2*2+3+2*4=18
一个bfs
//用图的方法解决//设置访问数组static HashMap<Node,Boolean> visited;static int solve(Node root,Node target){ans=0;visited=new HashMap<>();//图,hashmap可以更快找到,而没有采取下标对应结点HashMap<Node,ArrayList<Node>> graph=new HashMap<>();//树转为双向图,并且设置访问数组toGraph(root,graph);//广度优先遍历bfs(graph,target);return ans;}//深度优先转为双向图static void toGraph(Node root,HashMap<Node,ArrayList<Node>> graph){if(!graph.containsKey(root)){graph.put(root,new ArrayList<>());}if(root.left!=null){graph.get(root).add(root.left);toGraph(root.left,graph);graph.get(root.left).add(root);}if(root.right!=null){graph.get(root).add(root.right);toGraph(root.right,graph);graph.get(root.right).add(root);}visited.put(root,false);}static void bfs(HashMap<Node,ArrayList<Node>> graph,Node target){visited.put(target,true);Queue<Node> queue=new ArrayDeque<>();//加入第一层for (Node v:graph.get(target)){queue.offer(v);}//第一层深度为1int height=1;while (!queue.isEmpty()){int size=queue.size();//每次遍历一层for (int i = 0; i < size; i++) {Node v=queue.poll();if (!visited.get(v)){//设置访问数组visited.put(v,true);//记录答案ans+=height;//下一层添加for (Node next:graph.get(v)) {queue.offer(next);}}}//下一次深度+1height++;}}
所有代码
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Queue;public class Main {static class Node{int val;Node left;Node right;public Node(int v){val=v;}}public static void main(String[] args) {Node a=new Node(1);Node b=new Node(2);Node c=new Node(3);Node d=new Node(4);Node e=new Node(5);Node f=new Node(6);Node g=new Node(7);Node h=new Node(8);Node i=new Node(9);a.left=b;a.right=c;b.left=d;b.right=e;c.left=f;c.right=g;d.left=h;d.right=i;int res1=solve1(a);System.out.println(res1);//16int res2=solve2(a);System.out.println(res2);//26int res3=solve3(a,d);System.out.println(res3);//18//使用图来解决#3int res=solve(a,d);System.out.println(res);//18}//--------------------------------------------------------------------public static int solve1(Node root){sum=0;sumDepths(root,0);return sum;}static int sum;public static void sumDepths(Node root,int depth){sum+=depth;if(root.left!=null){sumDepths(root.left,depth+1);}if(root.right!=null){sumDepths(root.right,depth+1);}}//--------------------------------------------------------------------public static int solve2(Node root) {ans=0;dfs(root);return ans;}static class Info{int numNodes;int sumDepths;public Info(int a,int b){numNodes=a;sumDepths=b;}}static int ans;static Info dfs(Node root){Info pInfo=new Info(1,0);if(root.left!=null){Info cInfo=dfs(root.left);pInfo.sumDepths+=cInfo.sumDepths+cInfo.numNodes;pInfo.numNodes+=cInfo.numNodes;}if(root.right!=null){Info cInfo=dfs(root.right);pInfo.sumDepths+=cInfo.sumDepths+cInfo.numNodes;pInfo.numNodes+=cInfo.numNodes;}ans+= pInfo.sumDepths;return pInfo;}//--------------------------------------------------------------------//视频中把每个子树的结点数信息放到结点中//我把其放到哈希表中static HashMap<Node,Integer> map;//总结点个数static int n;static int solve3(Node root,Node target){ans=0;map=new HashMap<>();sumDists(root,target);return ans;}//把每个子树的结点数放到对应结点和结点数的map中static Info dfs1(Node root){Info pInfo=new Info(1,0);if(root.left!=null){Info cInfo=dfs1(root.left);pInfo.sumDepths+=cInfo.sumDepths+cInfo.numNodes;pInfo.numNodes+=cInfo.numNodes;}if(root.right!=null){Info cInfo=dfs1(root.right);pInfo.sumDepths+=cInfo.sumDepths+cInfo.numNodes;pInfo.numNodes+=cInfo.numNodes;}//和dfs的区别只有此处map.put(root, pInfo.numNodes);return pInfo;}static void dfs2(Node u,int sumDists,Node target){if(u==target){ans=sumDists;}if(u.left!=null){int newSumDists=sumDists-map.get(u.left)+(n-map.get(u.left));dfs2(u.left,newSumDists,target);}if(u.right!=null){int newSumDists=sumDists-map.get(u.right)+(n-map.get(u.right));dfs2(u.right,newSumDists,target);}}static int sumDists(Node root,Node target){Info info=dfs1(root);n=info.numNodes;dfs2(root,info.sumDepths,target);return ans;}//--------------------------------------------------------------------//用图的方法解决//设置访问数组static HashMap<Node,Boolean> visited;static int solve(Node root,Node target){ans=0;visited=new HashMap<>();//图,hashmap可以更快找到,而没有采取下标对应结点HashMap<Node,ArrayList<Node>> graph=new HashMap<>();//树转为双向图,并且设置访问数组toGraph(root,graph);//广度优先遍历bfs(graph,target);return ans;}//深度优先转为双向图static void toGraph(Node root,HashMap<Node,ArrayList<Node>> graph){if(!graph.containsKey(root)){graph.put(root,new ArrayList<>());}if(root.left!=null){graph.get(root).add(root.left);toGraph(root.left,graph);graph.get(root.left).add(root);}if(root.right!=null){graph.get(root).add(root.right);toGraph(root.right,graph);graph.get(root.right).add(root);}visited.put(root,false);}static void bfs(HashMap<Node,ArrayList<Node>> graph,Node target){visited.put(target,true);Queue<Node> queue=new ArrayDeque<>();//加入第一层for (Node v:graph.get(target)){queue.offer(v);}//第一层深度为1int height=1;while (!queue.isEmpty()){int size=queue.size();//每次遍历一层for (int i = 0; i < size; i++) {Node v=queue.poll();if (!visited.get(v)){//设置访问数组visited.put(v,true);//记录答案ans+=height;//下一层添加for (Node next:graph.get(v)) {queue.offer(next);}}}//下一次深度+1height++;}}}
2023-12-25 19:10:43