Skip to content

392. Is Subsequence

Jacky Zhang edited this page Oct 30, 2016 · 3 revisions

Given a string s and 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"

Return true.

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

Return false.

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?

##Approach 1: two pointers

解题思路为two pointers。时间复杂度为O(n)。

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

使用String.indexOf(int ch, int fromIndex)方法。

public class Solution {
    public boolean isSubsequence(String s, String t) {
        if(t.length() < s.length()) return false;
        int pre = 0;
        for(int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            pre = t.indexOf(c, pre);
            if(pre == -1) return false;
            pre++;
        }
        return true;
    }
}

##Approach 2: binary search

解题思路为先将t的char,index存入一个hash map中,map的key为char,value为List,因为会有相同的字符。

然后顺序扫描s,查找s的char c是否在map中,若不存在,则返回false; 若存在,则维护一个lowBound,只取map.get(c)中>=lowBound的那个index,并且把更新lowBound=index+1,若不存在这样的index,则返回false。

对t进行预处理,可以满足follow up中有许多s要判断的要求。

public class Solution {
    public boolean isSubsequence(String s, String t) {
        Map<Character, List<Integer>> map = new HashMap<>();
        for(int i = 0; i < t.length(); i++) {
            char c = t.charAt(i);
            if(!map.containsKey(c)) {
                map.put(c, new ArrayList<>());
            }
            map.get(c).add(i);
        }
        int lowBound = 0;
        for(int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if(!map.containsKey(c)) return false;
            List<Integer> list = map.get(c);
            int j = 0;
            for(; j < list.size(); j++) {
                int index = list.get(j);
                if(index >= lowBound) {
                    lowBound = index + 1;
                    break;
                }
            }
            if(j == list.size()) return false;
        }
        return true;
    }
}
Clone this wiki locally