792. 匹配子序列的单词数
给定字符串 s 和字符串数组 words, 返回 words[i] 中是s的子序列的单词个数 。
字符串的 子序列 是从原始字符串中生成的新字符串,可以从中删去一些字符(可以是none),而不改变其余字符的相对顺序。
例如, “ace” 是 “abcde” 的子序列。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/number-of-matching-subsequences
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
双指针
class Solution {
private boolean match(String str1, String str2) {
int p1 = 0, p2 = 0;
while (p1 < str1.length() && p2 < str2.length()) {
if (str1.charAt(p1) == str2.charAt(p2)) {
p1++;
p2++;
} else {
p1++;
}
}
return p2 == str2.length();
}
public int numMatchingSubseq(String s, String[] words) {
int ans = 0;
for (String word : words) {
if (match(s, word)) {
ans++;
}
}
return ans;
}
}
二分
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class Solution {
private int lower(List<Integer> data, int target) {
int left = 0, right = data.size() - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (data.get(mid) < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left == data.size() ? -1 : left;
}
public int numMatchingSubseq(String s, String[] words) {
if (s == null || words == null || words.length == 0) {
return 0;
}
List<Integer>[] helper = new List[26];
for (int i = 0; i < 26; ++i) {
helper[i] = new ArrayList<>();
}
for (int i = 0; i < s.length(); ++i) {
helper[s.charAt(i) - 'a'].add(i);
}
int ans = 0;
for (String word : words) {
int i;
int target = 0;
for (i = 0; i < word.length(); ++i) {
List<Integer> arr = helper[word.charAt(i) - 'a'];
int index = lower(arr, target);
if (index == -1) {
break;
}
target = arr.get(index) + 1;
}
if (i == word.length()) {
ans++;
}
}
return ans;
}
}
同时匹配
import java.util.ArrayDeque;
import java.util.Queue;
class Solution {
public int numMatchingSubseq(String s, String[] words) {
Queue<int[]>[] queue = new Queue[26];
for (int i = 0; i < 26; ++i) {
queue[i] = new ArrayDeque<>();
}
for (int i = 0; i < words.length; ++i) {
queue[words[i].charAt(0) - 'a'].offer(new int[]{i, 0});
}
int ans = 0;
for (int i = 0; i < s.length(); ++i) {
int x = s.charAt(i) - 'a';
int len = queue[x].size();
while (len-- > 0) {
int[] p = queue[x].poll();
if (p[1] == words[p[0]].length() - 1) {
ans++;
} else {
p[1]++;
queue[words[p[0]].charAt(p[1]) - 'a'].offer(p);
}
}
}
return ans;
}
}
动态规划
import java.util.ArrayList;
import java.util.List;
class Solution {
public int numMatchingSubseq(String t, String[] words) {
int[][] dp = new int[t.length()][26];
for (int i = t.length() - 1; i >= 0; i--) {
for (int j = 0; j < 26; j++) {
if (t.charAt(i) - 'a' == j) {
dp[i][j] = i;
} else {
dp[i][j] = (i == t.length() - 1) ? -1 : dp[i + 1][j];
}
}
}
int ans = 0;
for (String s: words) {
int idx = 0, next = 0;
while (idx < s.length() && next < t.length()) {
next = dp[next][s.charAt(idx) - 'a'];
if (next == -1) {
break;
}
idx ++;
next ++;
}
ans += idx == s.length() ? 1 : 0;
}
return ans;
}
}
心之所向,素履以往 生如逆旅,一苇以航