-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path1964-Find_the_Longest_Valid_Obstacle_Course_at_each_Position.cpp
More file actions
131 lines (117 loc) · 3.9 KB
/
1964-Find_the_Longest_Valid_Obstacle_Course_at_each_Position.cpp
File metadata and controls
131 lines (117 loc) · 3.9 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
131
/*******************************************************************************
* 1964-Find_the_Longest_Valid_Obstacle_Course_at_each_Position.cpp
* Billy.Ljm
* 07 May 2023
*
* =======
* Problem
* =======
* https://leetcode.com/problems/find-the-longest-valid-obstacle-course-at-each-position/
*
* You want to build some obstacle courses. You are given a 0-indexed integer
* array obstacles of length n, where obstacles[i] describes the height of the
* ith obstacle.
*
* For every index i between 0 and n - 1 (inclusive), find the length of the
* longest obstacle course in obstacles such that:
*
* - You choose any number of obstacles between 0 and i inclusive.
* - You must include the ith obstacle in the course.
* - You must put the chosen obstacles in the same order as they appear in
* obstacles.
* - Every obstacle (except the first) is taller than or the same height as the
* obstacle immediately before it.
*
* Return an array ans of length n, where ans[i] is the length of the longest
* obstacle course for index i as described above.
*
* ===========
* My Approach
* ===========
* We will use dynamic programming, where for each index, we find the earlier
* index with the maximum obstacle course length but with a shorter height.
* Then, we just have to add one to this found index.
* To find this index efficiently, we can create a dictionary of {height:length}
* for all earlier indices, and binary search any new indices within it. This
* is conveniently already implemented in std::map::upper_bound.
*
* This has a time complexity of O(n * log(n)) and space complexity of O(n),
* where n is the length of the array of obstacle heights.
******************************************************************************/
#include <iostream>
#include <vector>
#include <map>
/**
* Solution
*/
class Solution {
public:
/**
* Finds the longest obstacle course that be constructed with each element
* and any in-order combination of preceding elements. An obstacle course
* must have obstacles whose height are non-decreasing.
*
* @param obstacles height of the obstacles
*
* @return a vector where the i-th element is the maximum length of an
* obstacle course which includes obstacle[i]
*/
std::vector<int> longestObstacleCourseAtEachPosition(
std::vector<int>& obstacles) {
std::vector<int> ans; // max length at each index
std::map<int, int> height2length; // {height : max length} so far
for (int i = 0; i < obstacles.size(); i++) {
// find next smallest/equal height plus 1
auto it = height2length.upper_bound(obstacles[i]);
// if no smaller height found, then max length is 1
if (it == height2length.begin()) {
ans.push_back(1);
}
// else, add 1
else {
it--;
ans.push_back(it->second + 1);
it++;
}
// update larger heights w/ smaller lengths
while (it != height2length.end() && it->second <= ans[i]) {
it = height2length.erase(it);
}
// update current height
height2length[obstacles[i]] = ans[i];
}
return ans;
}
};
/**
* << operator for vectors
*/
template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
os << "[";
for (int i = 0; i < v.size(); i++) {
os << v[i] << ",";
}
os << "\b]";
return os;
}
/**
* Test cases
*/
int main(void) {
Solution sol;
std::vector<int> obstacles;
// test case 1
obstacles = { 1, 2, 3, 2 };
std::cout << "longestObstacleCourseAtEachPosition(" << obstacles << ") = "
<< sol.longestObstacleCourseAtEachPosition(obstacles) << std::endl;
// test case 2
obstacles = { 2, 2, 1 };
std::cout << "longestObstacleCourseAtEachPosition(" << obstacles << ") = "
<< sol.longestObstacleCourseAtEachPosition(obstacles) << std::endl;
// test case 3
obstacles = { 3, 1, 5, 6, 4, 2 };
std::cout << "longestObstacleCourseAtEachPosition(" << obstacles << ") = "
<< sol.longestObstacleCourseAtEachPosition(obstacles) << std::endl;
return 0;
}