-
Notifications
You must be signed in to change notification settings - Fork 0
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?
##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;
}
}