2022-8-9 剑指offer-队列
完全二叉树是每一层(除最后一层外)都是完全填充(即,节点数达到最大,第 n
层有 2n-1
个节点)的,并且所有的节点都尽可能地集中在左侧。
设计一个用完全二叉树初始化的数据结构 CBTInserter
,它支持以下几种操作:
CBTInserter(TreeNode root)
使用根节点为root
的给定树初始化该数据结构;CBTInserter.insert(int v)
向树中插入一个新节点,节点类型为TreeNode
,值为v
。使树保持完全二叉树的状态,并返回插入的新节点的父节点的值;CBTInserter.get_root()
将返回树的根节点。
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode() {} 8 * TreeNode(int val) { this.val = val; } 9 * TreeNode(int val, TreeNode left, TreeNode right) { 10 * this.val = val; 11 * this.left = left; 12 * this.right = right; 13 * } 14 * } 15 */ 16 class CBTInserter { 17 TreeNode root; 18 List<TreeNode> list; 19 public CBTInserter(TreeNode root) { 20 this.root=root; 21 list=new ArrayList<>(); 22 int num=count(root); 23 int index=0; 24 int[] nums={1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383}; 25 for (int i=0;i<nums.length;i++){ 26 if (num<=nums[i]){ 27 index=i; 28 break; 29 } 30 } 31 if (num==nums[index]){ 32 //最后一层 33 index++; 34 } 35 for (int i=0;i<index;i++){ 36 if (list.size()==0){ 37 list.add(root); 38 }else{ 39 Queue<TreeNode> queue=new LinkedList<>(); 40 int size=list.size(); 41 for (int j=0;j<size;j++){ 42 TreeNode node=list.get(0); 43 if (node.left!=null) queue.offer(node.left); 44 if (node.right!=null) queue.offer(node.right); 45 list.remove(0); 46 } 47 while (!queue.isEmpty()){ 48 list.add(queue.poll()); 49 } 50 } 51 } 52 } 53 54 public int insert(int v) { 55 int index=-1; 56 for (int i=0;i<list.size();i++){ 57 TreeNode node=list.get(i); 58 if (node.left==null||node.right==null){ 59 index=i; 60 break; 61 } 62 } 63 //System.out.println(list.get(index).val); 64 if (list.get(index).left==null){ 65 list.get(index).left=new TreeNode(v); 66 return list.get(index).val; 67 } 68 list.get(index).right=new TreeNode(v); 69 if (index!=list.size()-1) return list.get(index).val; 70 int ans=list.get(index).val; 71 Queue<TreeNode> queue=new LinkedList<>(); 72 int size=list.size(); 73 for (int j=0;j<size;j++){ 74 TreeNode node=list.get(0); 75 if (node.left!=null) queue.offer(node.left); 76 if (node.right!=null) queue.offer(node.right); 77 list.remove(0); 78 } 79 while (!queue.isEmpty()){ 80 list.add(queue.poll()); 81 } 82 return ans; 83 } 84 85 public TreeNode get_root() { 86 return root; 87 } 88 89 public int count(TreeNode node){ 90 if (node==null) return 0; 91 return count(node.left)+count(node.right)+1; 92 } 93 } 94 95 /** 96 * Your CBTInserter object will be instantiated and called as such: 97 * CBTInserter obj = new CBTInserter(root); 98 * int param_1 = obj.insert(v); 99 * TreeNode param_2 = obj.get_root(); 100 */
思路:倒数第二层和最后一层是可能加节点的位置,可以用队列存储这些节点,在加入后如果满节点就弹出队列。
比自己做的笨方法好。