392. Is Subsequence

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?

Solution1:Two pointers

思路:
Time Complexity: O(s.len + t.len) Space Complexity: O(1)

Solution2:Binary Search

For follow up: 如果t很长的话 且 很对不同s多次调用,可以使用这种方法先建立buildTPosMap,会快。
Time Complexity: O(s.len * log(t.len)) Space Complexity: O(1)
思路: 对t建立一个hashmap,是每个字符 -> 该字符所有位置组成list 的map。拿到s后,遍历s的每个字符,在map对应字符的位置list中,二分查找得到最近的可用位置,最近可用意味着是在前一个字符得到的位置之后(变量prev)的最近位置。(list一定是递增的,所以可以利用二分查找)

屏幕快照 2017-09-08 上午12.05.01.png

Solution1 Code:

class Solution1 {
    public boolean isSubsequence(String s, String t) {
        if (s.length() == 0) return true;
        int index_s = 0, index_t = 0;
        while (index_t < t.length()) {
            if (t.charAt(index_t) == s.charAt(index_s)) {
                index_s++;
                if (index_s == s.length()) return true;
            }
            index_t++;
        }
        return false;
    }
}

Solution2 Code:

class Solution2 {
    private List<Integer>[] t_pos_map = new List[256];
    
    public boolean isSubsequence(String s, String t) {
        buildTPosMap(t);
        
        int prev = 0;
        for (int i = 0; i < s.length(); i++) {
            if (t_pos_map[s.charAt(i)] == null) return false; 
            int j = Collections.binarySearch(t_pos_map[s.charAt(i)], prev);
            if (j < 0) j = -j - 1;
            if (j == t_pos_map[s.charAt(i)].size()) return false;
            prev = t_pos_map[s.charAt(i)].get(j) + 1;
        }
        return true;
    }
    
    private void buildTPosMap(String t) {
        for (int i = 0; i < t.length(); i++) {
            if (t_pos_map[t.charAt(i)] == null)
                t_pos_map[t.charAt(i)] = new ArrayList<>();
            t_pos_map[t.charAt(i)].add(i);
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容