Skip to content

Commit 596ed1c

Browse files
authored
2458. Height of Binary Tree After Subtree Removal Queries (#187)
1 parent 089caf0 commit 596ed1c

File tree

2 files changed

+150
-0
lines changed

2 files changed

+150
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,7 @@
487487
| 2439 | Minimize Maximum of Array | [Ruby](./algorithms/ruby/2439-minimize-maximum-of-array.rb) | Medium |
488488
| 2444 | Count Subarrays With Fixed Bounds | [Ruby](./algorithms/ruby/2444-count-subarrays-with-fixed-bounds.rb) | Hard |
489489
| 2448 | Minimum Cost to Make Array Equal | [Ruby](./algorithms/ruby/2448-minimum-cost-to-make-array-equal.rb) | Hard |
490+
| 2458 | Height of Binary Tree After Subtree Removal Queries | [Ruby](./algorithms/ruby/2458-height-of-binary-tree-after-subtree-removal-queries.rb) | Hard |
490491
| 2462 | Total Cost to Hire K Workers | [Python3](./algorithms/python3/2462-total-cost-to-hire-k-workers.py) | Medium |
491492
| 2466 | Count Ways To Build Good Strings | [Ruby](./algorithms/ruby/2466-count-ways-to-build-good-strings.rb) | Medium |
492493
| 2477 | Minimum Fuel Cost to Report to the Capital | [Ruby](./algorithms/ruby/2477-minimum-fuel-cost-to-report-to-the-capital.rb) | Medium |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# frozen_string_literal: true
2+
3+
# 2458. Height of Binary Tree After Subtree Removal Queries
4+
# https://leetcode.com/problems/height-of-binary-tree-after-subtree-removal-queries
5+
# Hard
6+
7+
=begin
8+
You are given the root of a binary tree with n nodes. Each node is assigned a unique value from 1 to n. You are also given an array queries of size m.
9+
You have to perform m independent queries on the tree where in the ith query you do the following:
10+
* Remove the subtree rooted at the node with the value queries[i] from the tree. It is guaranteed that queries[i] will not be equal to the value of the root.
11+
Return an array answer of size m where answer[i] is the height of the tree after performing the ith query.
12+
13+
Note:
14+
* The queries are independent, so the tree returns to its initial state after each query.
15+
* The height of a tree is the number of edges in the longest simple path from the root to some node in the tree.
16+
17+
Example 1:
18+
Input: root = [1,3,4,2,null,6,5,null,null,null,null,null,7], queries = [4]
19+
Output: [2]
20+
Explanation: The diagram above shows the tree after removing the subtree rooted at node with value 4.
21+
The height of the tree is 2 (The path 1 -> 3 -> 2).
22+
23+
Example 2:
24+
Input: root = [5,8,9,2,1,3,7,4,6], queries = [3,2,4,8]
25+
Output: [3,2,3,2]
26+
Explanation: We have the following queries:
27+
- Removing the subtree rooted at node with value 3. The height of the tree becomes 3 (The path 5 -> 8 -> 2 -> 4).
28+
- Removing the subtree rooted at node with value 2. The height of the tree becomes 2 (The path 5 -> 8 -> 1).
29+
- Removing the subtree rooted at node with value 4. The height of the tree becomes 3 (The path 5 -> 8 -> 2 -> 6).
30+
- Removing the subtree rooted at node with value 8. The height of the tree becomes 2 (The path 5 -> 9 -> 3).
31+
32+
Constraints:
33+
* The number of nodes in the tree is n.
34+
* 2 <= n <= 105
35+
* 1 <= Node.val <= n
36+
* All the values in the tree are unique.
37+
* m == queries.length
38+
* 1 <= m <= min(n, 104)
39+
* 1 <= queries[i] <= n
40+
* queries[i] != root.val
41+
=end
42+
43+
# Definition for a binary tree node.
44+
# class TreeNode
45+
# attr_accessor :val, :left, :right
46+
# def initialize(val = 0, left = nil, right = nil)
47+
# @val = val
48+
# @left = left
49+
# @right = right
50+
# end
51+
# end
52+
# @param {TreeNode} root
53+
# @param {Integer[]} queries
54+
# @return {Integer[]}
55+
def tree_queries(root, queries)
56+
@heights = Array.new(50000, 0)
57+
@len = 0
58+
@d = Array.new(100001, 0)
59+
@l = Array.new(100001, 0)
60+
@r = Array.new(100001, 0)
61+
62+
search(root, 0)
63+
64+
n = @len
65+
maxl = Array.new(n, 0)
66+
maxr = Array.new(n, 0)
67+
68+
(1...n).each do |i|
69+
maxl[i] = [maxl[i - 1], @heights[i - 1]].max
70+
maxr[n - i - 1] = [maxr[n - i], @heights[n - i]].max
71+
end
72+
73+
ret = []
74+
queries.each do |query|
75+
maxxl = maxl[@l[query]]
76+
maxxr = maxr[@r[query]]
77+
ret.push([maxxl, maxxr, @d[query] - 1].max)
78+
end
79+
80+
ret
81+
end
82+
83+
def search(p, h)
84+
@d[p.val] = h
85+
86+
if !p.left && !p.right
87+
@heights[@len] = h
88+
@l[p.val] = @r[p.val] = @len
89+
@len += 1
90+
return
91+
end
92+
93+
@l[p.val] = @len
94+
95+
search(p.left, h + 1) if p.left
96+
search(p.right, h + 1) if p.right
97+
98+
@r[p.val] = @len - 1
99+
end
100+
101+
# **************** #
102+
# TEST #
103+
# **************** #
104+
105+
require "test/unit"
106+
class TreeNode
107+
attr_accessor :val, :left, :right
108+
def initialize(val = 0, left = nil, right = nil)
109+
@val = val
110+
@left = left
111+
@right = right
112+
end
113+
end
114+
115+
class Test_tree_queries < Test::Unit::TestCase
116+
def setup
117+
# Example 1 tree setup
118+
@root1 = TreeNode.new(1)
119+
@root1.left = TreeNode.new(3)
120+
@root1.right = TreeNode.new(4)
121+
@root1.left.left = TreeNode.new(2)
122+
@root1.right.left = TreeNode.new(6)
123+
@root1.right.right = TreeNode.new(5)
124+
@root1.right.right.right = TreeNode.new(7)
125+
126+
# Example 2 tree setup
127+
@root2 = TreeNode.new(5)
128+
@root2.left = TreeNode.new(8)
129+
@root2.right = TreeNode.new(9)
130+
@root2.left.left = TreeNode.new(2)
131+
@root2.left.right = TreeNode.new(1)
132+
@root2.right.left = TreeNode.new(3)
133+
@root2.right.right = TreeNode.new(7)
134+
@root2.left.left.left = TreeNode.new(4)
135+
@root2.left.left.right = TreeNode.new(6)
136+
end
137+
138+
def test_example_1
139+
queries = [4]
140+
expected = [2]
141+
assert_equal expected, tree_queries(@root1, queries)
142+
end
143+
144+
def test_example_2
145+
queries = [3, 2, 4, 8]
146+
expected = [3, 2, 3, 2]
147+
assert_equal expected, tree_queries(@root2, queries)
148+
end
149+
end

0 commit comments

Comments
 (0)