975. Odd Even Jump
https://leetcode.com/problems/odd-even-jump/description/
从任何一点往后蹦,当这一蹦是奇数次蹦时就蹦到它后面第一个大于等于它的元素;否则就蹦到它后面第一个小于等于它的元素。问最后有几个点开始蹦能蹦到最后一个元素。问有多少种蹦法是用DP/Greedy。action分别为odd跳和even跳,受限于前面点even和odd跳是否成功,因此状态有对应even和odd两种。这道题要倒着遍历,一方面和Dungeon game一样限制来自于终点,最后一个点能否成功取决于它前面点能否成功;另一方面要找到底跳那个,即i点后面第一个大于等于/小于i的数要用到tree map,存后面所在的数,lower_bound即第一个大于等于它的,upper_bound为第一个大于它的,它的前一个即第一个小于等于它的。
代码参考花花。
/*
* @lc app=leetcode id=975 lang=cpp
*
* [975] Odd Even Jump
*
* https://leetcode.com/problems/odd-even-jump/description/
*
* algorithms
* Hard (46.06%)
* Likes: 409
* Dislikes: 120
* Total Accepted: 17.2K
* Total Submissions: 37.4K
* Testcase Example: '[10,13,12,14,15]'
*
* You are given an integer array A. From some starting index, you can make a
* series of jumps. The (1st, 3rd, 5th, ...) jumps in the series are called
* odd numbered jumps, and the (2nd, 4th, 6th, ...) jumps in the series are
* called even numbered jumps.
*
* You may from index i jump forward to index j (with i < j) in the following
* way:
*
*
* During odd numbered jumps (ie. jumps 1, 3, 5, ...), you jump to the index j
* such that A[i] <= A[j] and A[j] is the smallest possible value. If there
* are multiple such indexes j, you can only jump to the smallest such index
* j.
* During even numbered jumps (ie. jumps 2, 4, 6, ...), you jump to the index j
* such that A[i] >= A[j] and A[j] is the largest possible value. If there are
* multiple such indexes j, you can only jump to the smallest such index j.
* (It may be the case that for some index i, there are no legal jumps.)
*
*
* A starting index is good if, starting from that index, you can reach the end
* of the array (index A.length - 1) by jumping some number of times (possibly
* 0 or more than once.)
*
* Return the number of good starting indexes.
*
*
*
* Example 1:
*
*
* Input: [10,13,12,14,15]
* Output: 2
* Explanation:
* From starting index i = 0, we can jump to i = 2 (since A[2] is the smallest
* among A[1], A[2], A[3], A[4] that is greater or equal to A[0]), then we
* can't jump any more.
* From starting index i = 1 and i = 2, we can jump to i = 3, then we can't
* jump any more.
* From starting index i = 3, we can jump to i = 4, so we've reached the end.
* From starting index i = 4, we've reached the end already.
* In total, there are 2 different starting indexes (i = 3, i = 4) where we can
* reach the end with some number of jumps.
*
*
*
* Example 2:
*
*
* Input: [2,3,1,1,4]
* Output: 3
* Explanation:
* From starting index i = 0, we make jumps to i = 1, i = 2, i = 3:
*
* During our 1st jump (odd numbered), we first jump to i = 1 because A[1] is
* the smallest value in (A[1], A[2], A[3], A[4]) that is greater than or equal
* to A[0].
*
* During our 2nd jump (even numbered), we jump from i = 1 to i = 2 because
* A[2] is the largest value in (A[2], A[3], A[4]) that is less than or equal
* to A[1]. A[3] is also the largest value, but 2 is a smaller index, so we
* can only jump to i = 2 and not i = 3.
*
* During our 3rd jump (odd numbered), we jump from i = 2 to i = 3 because A[3]
* is the smallest value in (A[3], A[4]) that is greater than or equal to
* A[2].
*
* We can't jump from i = 3 to i = 4, so the starting index i = 0 is not good.
*
* In a similar manner, we can deduce that:
* From starting index i = 1, we jump to i = 4, so we reach the end.
* From starting index i = 2, we jump to i = 3, and then we can't jump anymore.
* From starting index i = 3, we jump to i = 4, so we reach the end.
* From starting index i = 4, we are already at the end.
* In total, there are 3 different starting indexes (i = 1, i = 3, i = 4) where
* we can reach the end with some number of jumps.
*
*
*
* Example 3:
*
*
* Input: [5,1,3,4,2]
* Output: 3
* Explanation:
* We can reach the end from starting indexes 1, 2, and 4.
*
*
*
*
*
*
* Note:
*
*
* 1 <= A.length <= 20000
* 0 <= A[i] < 100000
*
*/
class Solution {
public:
int oddEvenJumps(vector<int>& A) {
const int N = A.size();
vector<vector<bool>> dp(N, vector<bool>(2));
map<int, int> m;
m[A[N - 1]] = N - 1;
dp[N - 1][0] = dp[N - 1][1] = true;
int res = 1;
for (int i = N - 2; i >= 0; --i) {
// odd, 找第一个A[j] >= A[i]
// m中key第一个大于等于A[i]的
auto o = m.lower_bound(A[i]);
if (o != m.end()) dp[i][0] = dp[o->second][1];
// even, 找第一个A[j] <= A[i]
// m中第一个大于A[i]的
auto e = m.upper_bound(A[i]);
// 它前面那个即第一个小于等于的
if (e != m.begin()) dp[i][1] = dp[prev(e)->second][0];
if (dp[i][0]) ++res;
m[A[i]] = i;
}
return res;
}
};
Last updated
Was this helpful?