Maximum Number of Removable Characters

medium binary search string

Problem

Given s, p (p is a subsequence of s), and an array removable of distinct indices into s. Return the largest k such that removing removable[0..k-1] from s still leaves p as a subsequence.

Inputs = "abcacb", p = "ab", removable = [3,1,0]
Output2
After removing indices 3 and 1, p is still a subsequence.

def maximum_removals(s, p, removable):
    def ok(k):
        removed = set(removable[:k])
        j = 0
        for i, c in enumerate(s):
            if i in removed: continue
            if c == p[j]:
                j += 1
                if j == len(p): return True
        return False
    lo, hi = 0, len(removable)
    while lo < hi:
        mid = (lo + hi + 1) // 2
        if ok(mid): lo = mid
        else: hi = mid - 1
    return lo
function maximumRemovals(s, p, removable) {
  function ok(k) {
    const removed = new Set(removable.slice(0, k));
    let j = 0;
    for (let i = 0; i < s.length; i++) {
      if (removed.has(i)) continue;
      if (s[i] === p[j]) { if (++j === p.length) return true; }
    }
    return false;
  }
  let lo = 0, hi = removable.length;
  while (lo < hi) {
    const mid = Math.floor((lo + hi + 1) / 2);
    if (ok(mid)) lo = mid; else hi = mid - 1;
  }
  return lo;
}
class Solution {
    public int maximumRemovals(String s, String p, int[] removable) {
        int lo = 0, hi = removable.length;
        while (lo < hi) {
            int mid = (lo + hi + 1) / 2;
            if (ok(s, p, removable, mid)) lo = mid; else hi = mid - 1;
        }
        return lo;
    }
    boolean ok(String s, String p, int[] removable, int k) {
        Set<Integer> rem = new HashSet<>();
        for (int i = 0; i < k; i++) rem.add(removable[i]);
        int j = 0;
        for (int i = 0; i < s.length(); i++) {
            if (rem.contains(i)) continue;
            if (s.charAt(i) == p.charAt(j)) { if (++j == p.length()) return true; }
        }
        return false;
    }
}
bool ok(string& s, string& p, vector<int>& r, int k) {
    unordered_set<int> rem(r.begin(), r.begin() + k);
    int j = 0;
    for (int i = 0; i < (int)s.size(); i++) {
        if (rem.count(i)) continue;
        if (s[i] == p[j]) { if (++j == (int)p.size()) return true; }
    }
    return false;
}
int maximumRemovals(string s, string p, vector<int>& removable) {
    int lo = 0, hi = removable.size();
    while (lo < hi) {
        int mid = (lo + hi + 1) / 2;
        if (ok(s, p, removable, mid)) lo = mid; else hi = mid - 1;
    }
    return lo;
}
Time: O((m+n) log r) Space: O(r)