Leetcode::Odd Even Jump

point

Design

DP

MAP

Big O(time)

Code

DP

#define YetDecided -1
#define Impossible 0
#define Possible 1

#define EvenJump 0
#define OddJump 1

class Solution {
public:
    int n;
    vector<vector<int> > nxtPoint;
    vector<vector<int> > dp;

    bool isPossible(int cur, bool isEven, vector<int>& arr) {
        if (cur >= n) return Impossible;
        if (dp[cur][isEven] != YetDecided) return dp[cur][isEven];

        int nxtIdx = nxtPoint[cur][!isEven];
        if (nxtIdx == -1) 
            return dp[cur][isEven] = Impossible;
        return dp[cur][isEven] = isPossible(nxtIdx, !isEven, arr);
    }

    int oddEvenJumps(vector<int>& arr) {
        n = arr.size();
        dp = vector<vector<int> > (n+1, vector<int>(2, YetDecided));
        nxtPoint = vector<vector<int> > (n+1, vector<int>(2, -1));

        map<int, int> mp; // map[value] = {index}
        nxtPoint[n-1][OddJump] = nxtPoint[n-1][EvenJump] = -1;
        mp[arr[n-1]] = n-1;

        // Find next jump spot in O(NlogN)
        for(int i = n-2; i >= 0; i--) {
            auto it = mp.lower_bound(arr[i]);
            if (it != mp.end()) {
                nxtPoint[i][OddJump] = it->second;
            }
            mp[arr[i]] = i;
        }

        mp.clear();
        mp[-arr[n-1]] = n-1;
        
        for(int i = n-2; i >= 0; i--) {
            auto it = mp.lower_bound(-arr[i]);
            if (it != mp.end()) {
                nxtPoint[i][EvenJump] = (it->second);
            }
            mp[-arr[i]] = i;
        }

        int ans = 0;
        dp[n-1][OddJump] = dp[n-1][EvenJump] = Possible;

        for(int i = 0; i < n; i++) {
            bool ret = isPossible(i, false, arr);
            ans += ret;
        }
        return ans;
    }
};

MAP

class Solution {
public:
    int oddEvenJumps(vector<int>& arr) {
        int n = arr.size();

        map<int,int> mp;
        vector<int> higher(n, 0), lower(n, 0);

        int ret = 1;
        mp[arr[n-1]] = n-1;
        higher[n-1] = lower[n-1] = 1;

        for(int i = n-2; i >= 0; i--) {
            auto hi = mp.lower_bound(arr[i]), lo = mp.upper_bound(arr[i]);
            if (hi != mp.end()) higher[i] = lower[hi->second];
            if (lo != mp.begin()) lower[i] = higher[(--lo)->second];
            if (higher[i]) ret++;
            mp[arr[i]] = i;
        }
        return ret;
    }
};