Skip to content

Commit 0a2f6cc

Browse files
committed
Implement odd-even-jump
https://leetcode.com/problems/odd-even-jump time: 112ms time-rank: 36.46% time-complexity: O( N log( N ) ) space: 18.1MB space-rank: 100% space-complexity: O( N )
1 parent 68e0136 commit 0a2f6cc

File tree

2 files changed

+174
-0
lines changed

2 files changed

+174
-0
lines changed

odd-even-jump-test.cpp

Lines changed: 62 additions & 0 deletions
Large diffs are not rendered by default.

odd-even-jump.cpp

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2019 Christopher Friedt
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
#include <map>
26+
#include <vector>
27+
28+
using namespace std;
29+
30+
// https://leetcode.com/problems/odd-even-jump/
31+
32+
class Solution {
33+
public:
34+
int oddEvenJumps(vector<int>& A) {
35+
36+
enum {
37+
EVEN,
38+
ODD,
39+
};
40+
41+
const size_t N = A.size();
42+
43+
// Pre-construct a 2xN table of next hops (or SIZE_MAX when there is
44+
// no possible hop). This should be done in O( N log( N ) ) time or
45+
// better.
46+
47+
//
48+
// For a given odd or even state, each step i has (at most) one next
49+
// element j, i < j.
50+
//
51+
// The question is, how do you efficiently compute the next steps?
52+
53+
// XXX: @CJF: I got stuck on this part. Originally, I was using
54+
// a sorted vector and an unordered_map. The combined complexity was
55+
// N log N, so I should have realized it was easier to just use an
56+
// ordered map.
57+
map<int,size_t> next;
58+
59+
// Since step i depends only on step j (j > i), to reach the goal, then
60+
// cache the results in reverse order. Step N - 1 is true (for both odd
61+
// and even) since starting at the goal means it is reachable.
62+
vector<vector<bool>> cache( 2, vector<bool>( N ) );
63+
cache[ EVEN ][ N - 1 ] = true;
64+
cache[ ODD ][ N - 1 ] = true;
65+
int ngood = 1;
66+
67+
next[ A[ N - 1 ] ] = N - 1;
68+
69+
// O( N )
70+
for( size_t N = A.size(), k = N - 1; k > 0; --k ) {
71+
const size_t i = k - 1;
72+
size_t j;
73+
74+
auto it = next.find( A[ i ] );
75+
if ( next.end() == it ) {
76+
77+
// https://leetcode.com/problems/odd-even-jump/discuss/378369/c-equivalent-of-treemap
78+
auto lower = next.lower_bound( A[ i ] );
79+
if ( lower == next.begin() ) {
80+
lower = next.end();
81+
} else {
82+
lower--;
83+
}
84+
if ( next.end() != lower ) {
85+
j = lower->second;
86+
cache[ EVEN ][ i ] = cache[ ODD ][ j ];
87+
}
88+
89+
auto higher = next.upper_bound( A[ i ] );
90+
if ( next.end() != higher ) {
91+
j = higher->second;
92+
cache[ ODD ][ i ] = cache[ EVEN ][ j ];
93+
}
94+
95+
} else {
96+
97+
j = it->second;
98+
cache[ EVEN ][ i ] = cache[ ODD ][ j ];
99+
cache[ ODD ][ i ] = cache[ EVEN][ j ];
100+
}
101+
102+
// always use the lower index (true since we are decreasing i monotonically)
103+
next[ A[ i ] ] = i;
104+
105+
if ( cache[ ODD ][ i ] ) {
106+
ngood++;
107+
}
108+
}
109+
110+
return ngood;
111+
}
112+
};

0 commit comments

Comments
 (0)