-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcount-complete-tree-nodes.rs
90 lines (75 loc) · 2.4 KB
/
count-complete-tree-nodes.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#![allow(dead_code, unused, unused_variables)]
fn main() {}
struct Solution;
// Definition for a binary tree node.
#[derive(Debug, PartialEq, Eq)]
pub struct TreeNode {
pub val: i32,
pub left: Option<Rc<RefCell<TreeNode>>>,
pub right: Option<Rc<RefCell<TreeNode>>>,
}
impl TreeNode {
#[inline]
pub fn new(val: i32) -> Self {
TreeNode {
val,
left: None,
right: None,
}
}
}
use std::cell::RefCell;
use std::rc::Rc;
impl Solution {
/// 普通遍历树,时间复杂度为O(n)
pub fn count_nodes1(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
if root.is_none() {
return 0;
}
let left = Self::count_nodes1(root.as_ref().unwrap().borrow_mut().left.take());
let right = Self::count_nodes1(root.as_ref().unwrap().borrow_mut().right.take());
1 + left + right
}
/// 二分法。
pub fn count_nodes(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
// 获取树的高度
fn get_level(node: Option<&Rc<RefCell<TreeNode>>>) -> i32 {
if node.is_none() {
return 0;
}
return 1 + get_level(node.unwrap().borrow().left.as_ref());
}
let level = get_level(root.as_ref());
if level == 0 {
return 0;
} else if level == 1 {
return 1;
}
let (mut min_count, mut max_count) = (2i32 << (level - 2), (2i32 << (level - 1)) - 1);
// 查看中位的节点是否存在
fn exists(node: Option<&Rc<RefCell<TreeNode>>>, middle: i32, level: i32) -> bool {
if level == 1 {
return node.is_some();
}
if ((1 << 31) | (middle << (33 - level))) == middle << (33 - level) {
exists(node.unwrap().borrow().right.as_ref(), middle, level - 1)
} else {
exists(node.unwrap().borrow().left.as_ref(), middle, level - 1)
}
}
while max_count - min_count > 1 {
let middle = (min_count + max_count) / 2;
let e = exists(root.as_ref(), middle, level);
if e {
min_count = middle;
} else {
max_count = middle - 1;
}
}
if max_count - min_count == 1 && exists(root.as_ref(), max_count, level) {
max_count
} else {
min_count
}
}
}