题目描述:
题目链接:https://leetcode-cn.com/problems/occurrences-after-bigram
给出第一个词 first 和第二个词 second,考虑在某些文本 text 中可能以 "first second third" 形式出现的情况,其中 second 紧随 first 出现,third 紧随 second 出现。
对于每种这样的情况,将第三个词 "third" 添加到答案中,并返回答案。
示例1:
输入:text = "alice is a good girl she is a good student", first = "a", second = "good"
输出:["girl","student"]
题目分析:
一般思路:
简单题型,思路很清晰,将text按照 ' ' 分割(字符串分割),然后滑动窗口(窗口大小为3),判断窗口中第一个元素是否为first,第二个元素是否为second,如果同时满足,那么就将第三个字符串加入结果集,最后返回结果集。(其中字符串分割,一次遍历,滑动窗口判断,一次遍历,并且字符串分割需要一个数组的空间存放分割后的字符串)
代码:(LeeCode官方答案)
https://leetcode-cn.com/problems/occurrences-after-bigram/solution/bigram-fen-ci-by-leetcode-solution-7q3e/
public String[] findOcurrences(String text, String first, String second) {
String[] words = text.split(" ");
List<String> list = new ArrayList<String>();
for (int i = 2; i < words.length; i++) {
if (words[i - 2].equals(first) && words[i - 1].equals(second)) {
list.add(words[i]);
}
}
int size = list.size();
String[] ret = new String[size];
for (int i = 0; i < size; i++) {
ret[i] = list.get(i);
}
return ret;
}
一次遍历,常数空间实现思路:
将分割字符串遍历和滑动窗口判断结合:在分割时维护一个queue,只存放三个字符串大小,当queue的大小为3时进行一次判断,第一个元素是否为first,第二个元素是否为second,如果同时满足,那么就将第三个字符串加入结果集,最后返回结果集。
public String[] findOcurrences(String text, String first, String second) {
//字符串分割,用一个list接收
List<String> list = new ArrayList<>();
//1.分割字符串
int pre = 0, cnt = 0;
//2.在分割时用一个大小为3的queue存储
Deque<String> queue=new LinkedList<>();
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == ' '||i==text.length()-1) {
String s = i == text.length() - 1 ? text.substring(pre) :
text.substring(pre, i);
pre = i + 1;
queue.offer(s);
if(queue.size()==3){
if(queue.pop().equals(first)&&queue.peek().equals(second))
list.add(s);
}
}
}
String[] res = new String[list.size()];
for (int i = 0; i < list.size(); i++) {
res[i] = list.get(i);
}
return res;
}