题目描述:
给定一个字符串来代表一个学生的出勤纪录,这个纪录仅包含以下三个字符:
- 'A' : Absent,缺勤
- 'L' : Late,迟到
- 'P' : Present,到场
如果一个学生的出勤纪录中不超过一个'A'(缺勤)并且不超过两个连续的'L'(迟到),那么这个学生会被奖赏。
你需要根据这个学生的出勤纪录判断他是否会被奖赏。
示例 1:
输入: "PPALLP"
输出: True
示例 2:
输入: "PPALLL"
输出: False
分析:
分两步,第一步查看‘A’的个数是否大于1,第二步判断 ‘L’ 连续出现的个数是否大于2,即转化为判断字符串中是否包含“LLL” 即可。
普通方法可以使用String类方法,通过判断s.indexOf('A')和s.lastindexOf('A')是否相等可以知道‘A’字母的个数是否大于1,同时我们也可以使用s.contains("LLL")来判断字符串中是否包含“LLL”。
以上方法看上去很简单,但是觉得不应该为写代码而写代码,所以给自己增加点小难度,使用kmp算法,算是巩固一下KMP算法。
代码:
class Solution {
public boolean checkRecord(String s) {
if(s.length()==0||s.length()==1)return true;
else if(s.length()==2)return !s.equals("AA");
else return judgeA(s)&&judgeLL(s);
}
public boolean judgeA(String s){//查看A的个数是否大于1
int flag=0;
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='A'){
if(flag==0)
flag=1;
else
return false;
}
}
return true;
}
public boolean judgeLL(String s){//kmp算法,查看字符串‘L’连续出现的个数是否大于2,即判断字符串中是否包含“LLL”即可
String find="LLL";
int[] next=new int[find.length()+1];
int k=0;
next[0]=next[1]=0;
for(int i=1;i<find.length();i++){//求next数组
while(k!=0&&s.charAt(i)!=s.charAt(k))
k=next[k];
if(s.charAt(i)==s.charAt(k))
k++;
next[i+1]=k;
}
for(int i=0,j=0;i<s.length();i++){//字符串匹配
while(j!=0&&s.charAt(i)!=find.charAt(j))
j=next[j];
if(s.charAt(i)==find.charAt(j)){
j++;
}
if(j==find.length())
return false;
}
return true;
}
}