面试题 04.03. 特定深度节点链表
给定一棵二叉树,设计一个算法,创建含有某一深度上所有节点的链表(比如,若一棵树的深度为 D,则会创建出 D 个链表)。返回一个包含所有深度的链表的数组。
示例:
输入:[1,2,3,4,5,null,7,8]
1
/ \
2 3
/ \ \
4 5 7
/
8
输出:[[1],[2,3],[4,5,7],[8]]
解析过程:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
//层次遍历,将每一层的节点值加入链表
public ListNode[] listOfDepth(TreeNode tree) {
List<ListNode> list=new ArrayList<>();
Queue<TreeNode> queue=new LinkedList<>();
queue.offer(tree);
while(!queue.isEmpty()){
int size=queue.size();
ListNode lnode=new ListNode();
for(int i=0;i<size;i++){
TreeNode cur=queue.poll();
lnode.next=new ListNode(cur.val);
lnode=lnode.next;
if(cur.left!=null){
queue.offer(cur.left);
}
if(cur.right!=null){
queue.offer(cur.right);
}
// 将头结点放入list中
if(i==0){
list.add(lnode);
}
}
}
/*
toArray():
1.不带参数的toArray方法,是构造的一个Object数组,然后进行数据拷贝,此时进行转型就会产生ClassCastException(类型转换的锅)
2.带参数的toArray方法,则是根据参数数组的类型,构造了一个对应类型的,长度跟ArrayList的size一致的空数组,虽然方法本身还是以 Object数组的形式返回结果,不过由于构造数组使用的ComponentType跟需要转型的ComponentType一致,就不会产生转型异常。
*/
return list.toArray(new ListNode[list.size()]);
}
}
结果:
执行用时:1 ms, 在所有 Java 提交中击败了84.81%的用户
内存消耗:36.7 MB, 在所有 Java 提交中击败了67.52%的用户
通过测试用例:49 / 49
面试题 04.06. 后继者
设计一个算法,找出二叉搜索树中指定节点的“下一个”节点(也即中序后继)。
如果指定节点没有对应的“下一个”节点,则返回null。
示例 1:
输入: root = [2,1,3], p = 1
2
/ \
1 3
输出: 2
示例 2:
输入: root = [5,3,6,2,4,null,null,1], p = 6
5
/ \
3 6
/ \
2 4
/
1
输出: null
解析过程:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
//先中序遍历得到一个有序集合,然后判断指定节点的下一个节点是否存在
List<TreeNode> list=new ArrayList<>();
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
if(root==null){
return null;
}
Inorder(root);
int value=0;
for(int i=0;i<list.size();i++){
if(list.get(i).val==p.val){
value=i+1;
}
}
return value<list.size()?list.get(value):null;
}
//中序遍历
public void Inorder(TreeNode node){
if(node==null){
return;
}
Inorder(node.left);
list.add(node);
Inorder(node.right);
}
}
结果:
执行用时:6 ms, 在所有 Java 提交中击败了8.59%的用户
内存消耗:39.7 MB, 在所有 Java 提交中击败了5.41%的用户
通过测试用例:24 / 24
面试题 17.12. BiNode
二叉树数据结构TreeNode可用来表示单向链表(其中left置空,right为下一个链表节点)。实现一个方法,把二叉搜索树转换为单向链表,要求依然符合二叉搜索树的性质,转换操作应是原址的,也就是在原始的二叉搜索树上直接修改。
返回转换后的单向链表的头节点。
注意:本题相对原题稍作改动
示例:
输入: [4,2,5,1,3,null,6,0]
输出: [0,null,1,null,2,null,3,null,4,null,5,null,6]
解析过程:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
TreeNode head;
TreeNode pre=null;
public TreeNode convertBiNode(TreeNode root) {
if(root == null){
return null;
}
Inorder(root);
return head;
}
/*
用flag旗标来记录第一个左子树为空的点,即搜索树最左下角的点,并把它作为头结点
*/
public void Inorder(TreeNode node) {
if(node == null){
return;
}
Inorder(node.left);
visit(node);
Inorder(node.right);
}
public void visit(TreeNode Node){
if(pre==null){
head=Node;
}else {
//将节点的左节点置空,然后由pre连接该节点,该节点作为pre的右节点
Node.left=null;
pre.right=Node;
}
pre=Node;
}
}
结果:
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:44.1 MB, 在所有 Java 提交中击败了25.39%的用户
通过测试用例:34 / 34