-
-
Notifications
You must be signed in to change notification settings - Fork 223
Expand file tree
/
Copy pathnumberOfPeopleSeeInQueue.js
More file actions
130 lines (106 loc) · 3.82 KB
/
numberOfPeopleSeeInQueue.js
File metadata and controls
130 lines (106 loc) · 3.82 KB
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
class MyStack {
constructor() {
this.items = [];
}
// Core stack operations
push(value) {
this.items.push(value);
}
pop() {
if (this.isEmpty()) {
throw new Error("Stack Underflow: Cannot pop from an empty stack.");
}
return this.items.pop();
}
peek() {
if (this.isEmpty()) {
throw new Error("Stack Underflow: Cannot peek from an empty stack.");
}
return this.items[this.items.length - 1];
}
// Helper functions
isEmpty() {
return this.items.length === 0;
}
size() {
return this.items.length;
}
printStack() {
return this.items.join(' ');
}
}
/**
* Approach 1: Using a monotonic stack with native array operations
* Calculate how many people each person can see to their right in the queue
* @param {number[]} heights - Array of heights of people in the queue
* @returns {number[]} - Array where each element is the number of people visible from that position
*/
function canSeePersonsCount1(heights) {
// Input validation
if (!Array.isArray(heights) || heights.length === 0) {
throw new Error("Input must be a non-empty array of heights");
}
const length = heights.length;
const visibilityCount = Array(length).fill(0);
const stack = [];
// Process from right to left (as we're looking rightward)
for (let i = length - 1; i >= 0; i--) {
// Pop shorter people from stack as they're blocked by current person
while (stack.length && heights[i] > stack[stack.length - 1]) {
stack.pop();
visibilityCount[i]++; // Current person can see the popped person
}
// If stack is not empty, current person can see one more person (the first taller one)
if (stack.length) {
visibilityCount[i]++;
}
stack.push(heights[i]);
}
return visibilityCount;
}
/**
* Approach 2: Using the custom MyStack class implementation
* Calculate how many people each person can see to their right in the queue
* @param {number[]} heights - Array of heights of people in the queue
* @returns {number[]} - Array where each element is the number of people visible from that position
*/
function canSeePersonsCount2(heights) {
// Input validation
if (!Array.isArray(heights) || heights.length === 0) {
throw new Error("Input must be a non-empty array of heights");
}
const length = heights.length;
const visibilityCount = Array(length).fill(0);
const stack = new MyStack();
// Process from right to left (as we're looking rightward)
for (let i = length - 1; i >= 0; i--) {
// Pop shorter people from stack as they're blocked by current person
while (!stack.isEmpty() && heights[i] > stack.peek()) {
stack.pop();
visibilityCount[i]++; // Current person can see the popped person
}
// If stack is not empty, current person can see one more person (the first taller one)
if (!stack.isEmpty()) {
visibilityCount[i]++;
}
stack.push(heights[i]);
}
return visibilityCount;
}
// Test cases
const heights1 = [10, 6, 8, 5, 11, 9];
console.log("Approach 1 result:", canSeePersonsCount1(heights1));
const heights2 = [6, 5, 4, 3, 2, 1];
console.log("Approach 1 result:", canSeePersonsCount1(heights2));
const heights3 = [1, 2, 3, 4, 5, 6];
console.log("Approach 1 result:", canSeePersonsCount1(heights3));
console.log("--------------------------------");
console.log("Approach 2 result:", canSeePersonsCount2(heights1));
console.log("Approach 2 result:", canSeePersonsCount2(heights2));
console.log("Approach 2 result:", canSeePersonsCount2(heights3));
// Edge case test
try {
canSeePersonsCount1([]);
} catch (e) {
console.error("Error handling test:", e.message);
}