Is Subsequence

Given a stringsand a string t, check if s is subsequence of t.

You may assume that there is only lower case English letters in both s and t. t is potentially a very long (length ~= 500,000) string, and s is a short string (<=100).

A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie,"ace"is a subsequence of "abcde"while"aec"is not).

Example 1:
s="abc",t="ahbgdc"

Returntrue.

Example 2:
s="axc",t="ahbgdc"

Returnfalse.

Follow up:
If there are lots of incoming S, say S1, S2, ... , Sk where k >= 1B, and you want to check one by one to see if T has its subsequence. In this scenario, how would you change your code?

Solution #1:

Iterate through t, construct a index dictionary based on characters. The index list for each character will be in ascending order (sorted). Iterate through s. Starting with predicted next index 0, binary search the first element >= next index. If found, next index = found index + 1. If not found, s is not a sub sequence of t.

public boolean isSubsequence(String s, String t) {
    HashMap<Character, List<Integer>> dict = new HashMap<>();
    for (int i = 0; i < t.length(); i++) {
        char key = t.charAt(i);
        if (!dict.containsKey(key)) {
            dict.put(key, new ArrayList<Integer>());
        }
        dict.get(key).add(i);
    }

    int nextIndex = 0;
    for (int i = 0; i < s.length(); i++) {
        char key = s.charAt(i);
        if (!dict.containsKey(key)) {
            return false;
        }
        int left  = 0,
            right = dict.get(key).size() - 1;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (dict.get(key).get(mid) >= nextIndex) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        if (dict.get(key).get(left) < nextIndex) {
            return false;
        }
        nextIndex = dict.get(key).get(left) + 1;
    }
    return true;
}

Solution #2:

Two pointers.

public boolean isSubsequence(String s, String t) {
    if (s == null || s.length() == 0) {
        return true;
    }
    int sIndex = 0,
        tIndex = 0;
    while (tIndex < t.length()) {
        if (t.charAt(tIndex) == s.charAt(sIndex)) {
            sIndex++;
            if (sIndex == s.length()) {
                return true;
            }
        }
        tIndex++;
    }
    return false;
}

results matching ""

    No results matching ""