-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcount-complete-tree-nodes.js
145 lines (135 loc) · 3.8 KB
/
count-complete-tree-nodes.js
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/**
* Source: https://leetcode.com/problems/count-complete-tree-nodes/
* Tags: [Tree,Binary Search]
* Level: Medium
* Title: Count Complete Tree Nodes
* Auther: @imcoddy
* Content: Given a complete binary tree, count the number of nodes.
*
* Definition of a complete binary tree from Wikipedia:
* In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h.
*/
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
/**
* Memo: Since this is a complete tree, if root.right could already be a perfect tree already. in this case, calculate its nodes directly as nodes = 2^height - 1.
* Complex: O(logn*logn)
* Runtime: 380ms
* Tests: 19 test cases passed
* Rank: S
*/
var countNodes = function(root) {
function count(root) {
if (!root) return 0;
var left = 1;
var right = 1;
var node = root.left;
while (node) {
node = node.left;
left++;
}
var node = root.right;
while (node) {
node = node.right;
right++;
}
return right === left ? Math.pow(2, right) - 1 : count(root.left) + count(root.right) + 1;
}
return count(root);
};
/**
* Memo: A bit improve of the solution above.
* Complex: O(logn*logn)
* Runtime: 365ms
* Tests: 19 test cases passed
* Rank: S
* Updated: 2015-06-09
*/
var countNodes = function(root) {
function count(root) {
if (!root) return 0;
var heightL = 1;
var heightR = 1;
var nodeL = root.left;
var nodeR = root.right;
while (nodeR) {
nodeL = nodeL.left;
nodeR = nodeR.right;
heightL++;
heightR++;
}
return nodeL === null ? Math.pow(2, heightR) - 1 : count(root.left) + count(root.right) + 1;
}
return count(root);
};
/**
* Memo: Binary Search Solution
* Complex: O(logn)
* Runtime: 324ms
* Tests: 18 test cases passed
* Rank: B
* Updated: 2015-06-26
*/
var countNodes = function(root) {
function count(root) {
if (!root) return 0;
var hl = 1;
var hr = 1;
var node = root;
while (node = node.left) hl++;
node = root;
while (node = node.right) hr++;
if (hl === hr) {
return Math.pow(2, hl) - 1;
} else {
return count(root.left) + count(root.right) + 1;
}
}
return count(root);
};
/**
* Memo: Improve version
* Complex: O(log*logn)
* Runtime: 276ms
* Tests: 18 test cases passed
* Rank: S
* Updated: 2015-06-27
*/
var countNodes = function(root) {
function count(root) {
if (!root) return 0;
var hl = 1;
var hr = 1;
var nl = root.left;
var nr = root.right;
while (nr) {
nl = nl.left;
nr = nr.right;
hl++;
hr++;
}
return nl === null ? Math.pow(2, hl) - 1 : count(root.left) + count(root.right) + 1;
}
return count(root);
};
var util = require("./util.js");
var should = require('should');
console.time('Runtime');
countNodes(util.arrayToTree([])).should.equal(0);
countNodes(util.arrayToTree([1])).should.equal(1);
countNodes(util.arrayToTree([1, 2])).should.equal(2);
countNodes(util.arrayToTree([1, 2, 3])).should.equal(3);
countNodes(util.arrayToTree([1, 2, 3, 4])).should.equal(4);
countNodes(util.arrayToTree([1, 2, 3, 4, 5])).should.equal(5);
countNodes(util.arrayToTree([1, 2, 3, 4, 5, 6, 7])).should.equal(7);
countNodes(util.arrayToTree([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])).should.equal(10);
console.timeEnd('Runtime');