leetcode IsSubsequence
z
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class IsSubsequence {
/**
* 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?
*/

// first edition
public boolean isSubsequence(String s, String t) {
int i=0;
int j=0;

while(i<s.length() && j<t.length()){
if (s.charAt(i) == t.charAt(j)){
i++;
j++;
}
else{
j++;
}
}
if (i==s.length())
return true;
else
return false;
}

// second edition
public boolean isSubsequence2(String s, String t) {
int index = -1;
for (char c : s.toCharArray()) {
index = t.indexOf(c, index + 1);
if (index == -1) return false;
}
return true;
}

// consider the follow ups. when there is a large number of s, it's expensive to loop t over and over again,
// therefore, a pre-calculate should be performed to find every letter in t and then, using their's positions to determine
// if s is a substring.
public boolean isSubsequence3(String s, String t){
List<Integer>[] l = new List[28];
for (int i=0; i<t.length(); i++){
if (l[t.charAt(i)-'a'] == null)
l[t.charAt(i)-'a'] = new ArrayList<>();
l[t.charAt(i)-'a'].add(i);
}

int min = -1;
for (int i = 0; i < s.length(); i++) {
if (l[s.charAt(i)] == null) return false; // Note: char of S does NOT exist in T causing NPE
int j = Collections.binarySearch(l[s.charAt(i)], min);
if (j < 0) j = -j - 1;
if (j == l[s.charAt(i)].size()) return false;
min = l[s.charAt(i)].get(j) + 1;
}
return true;

}
}