题目出处:https://leetcode-cn.com/problems/jump-game-vii/
方法一:递归方法(超时)
class Solution {
private:
bool flag = false;
public:
void dfs(int start, vector<bool>& vis, string &s, int& minJump, int& maxJump){
int nextl = start + minJump;
int nextr = start + maxJump;
if(nextl <= s.length()-1 && nextr >= s.length()-1 && s[s.length()-1] == '0'){
flag = true;
return;
}
for(int g = nextl; g <= min(nextr, (int)(s.length()-1)) && !flag; ++g){
if(s[g] == '0' && !vis[g]){
vis[g] = true;
dfs(g, vis, s, minJump, maxJump);
vis[g] = false;
}
}
}
bool canReach(string s, int minJump, int maxJump) {
if(s[s.length()-1] == '1'){
return false;
}
vector<bool> vis(s.length(), false);
dfs(0, vis, s, minJump, maxJump);
return flag;
}
};
方法二:树状数组
inline int lowbit(int x) {
return x & (-x);
}
class Solution {
public:
bool canReach(string s, int minJump, int maxJump) {
int n = s.size();
if (s[n - 1] == '1')
return false;
vector<int> zero;
for (int i = 0; i < n; ++i)
if (s[i] == '0')
zero.emplace_back(i);
int m = zero.size();
vector<int> a(m + 1);
auto query = [&](int pos) {
int ans = 0;
for (; pos; pos -= lowbit(pos))
ans += a[pos];
return ans;
};
auto update = [&](int pos, int val) {
for (; pos <= m; pos += lowbit(pos))
a[pos] += val;
};
update(1, 1);
update(2, -1);
int l = 0, r = 0;
for (int i = 1; i < m; ++i) {
if (query(i) > 0) {
while (l < m && zero[l] < zero[i - 1] + minJump)
l++;
while (r < m && zero[r] <= zero[i - 1] + maxJump)
r++;
update(l + 1, 1), update(r + 1, -1);
}
}
return query(m) > 0;
}
};
方法三:平衡二叉搜索树
思路:用有序集合维护所有为0的位置。将已经可以额到达的位置从集合中删除。
class Solution {
public:
bool canReach(string s, int minJump, int maxJump) {
int n = s.size();
if (s[n - 1] == '1')
return false;
vector<int> zero;
for (int i = 0; i < n; ++i)
if (s[i] == '0')
zero.emplace_back(i);
int m = zero.size();
vector<bool> can(n);
can[0] = true;
set<int> st(zero.begin(), zero.end());
for (int i = 0; i + 1 < m; ++i) {
if (can[zero[i]]) {
vector<int> destinations;
for (auto it = st.lower_bound(zero[i] + minJump); it != st.upper_bound(zero[i] + maxJump); ++it) {
destinations.emplace_back(*it);
}
for (int destination : destinations) {
can[destination] = true;
st.erase(destination);
}
}
}
return can[n - 1];
}
};