1、题目描述
给定两个字符串s1 和 s2 和正整数k,其中 s1 长度为 n1,s2 长度为 n2, 在s2中选一个子串,满足:
该子串长度为n1+k;
该子串中包含s1中全部字母;
该子串每个字母出现次数不小于s1中对应的字母, 我们称s2以长度k冗余覆盖s1, 给定s1,s2,k, 求最左侧的s2以长度k冗余覆盖s1的子串的首个元素的下标, 如果没有返回-1。
2、输入描述
输入为三行:
第一行为 s1
第二行为 s1
第三行为 k
s1和s2都只包含小写字母。
3、输出描述
最左侧的 s2 以长度 k 冗余覆盖 s1 的子串的首个元素下标,若不存在,则返回-1。
用例:
输入
ab
aabcd
1
输出
0
温馨提示!!!
华为OD机试考试官方会对考生代码查重。华为od机试因为有题库所以有很大的概率抽到原题。如果碰到了题库中的原题,千万不要直接使用题解中的代码,一定要做些修改,比如代码中的变量名,除此之外,代码的组织结构和逻辑也要进行一些改变,所以在日常的刷题中,要提前编写好属于自己的代码。
4、题解
使用数组记录s1中每个字母出现的次数,遍历s2字符串,每次截取s1.length()+k(窗口大小)大小的字符串,判断是否满足题目中的条件。
代码如下:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s1 = sc.nextLine();
String s2 = sc.nextLine();
int k = Integer.parseInt(sc.nextLine());
if (s1.length() + k > s2.length()) {
System.out.println(-1);
return;
}
// 记录s1中每个字母出现次数
int[] arr1 = new int[128];
for (char ch : s1.toCharArray()) {
arr1[ch] += 1;
}
int len = s1.length() + k;
for (int i=0; i<s2.length(); i++) {
if (i + len < s2.length()) {
String s = s2.substring(i, i + len);
if (isRight(s, arr1, s1)) {
System.out.println(i);
return;
}
}
}
System.out.println(-1);
}
private static boolean isRight(String s, int[] arr, String s1) {
int[] arr2 = new int[128];
for (char ch : s.toCharArray()) {
arr2[ch] += 1;
}
for (char ch : s1.toCharArray()) {
// 如果s1中某个字符出现次数大于s2则返回false
if (arr[ch] > arr2[ch]) {
return false;
}
}
return true;
}
执行结果如下: