【华为OD】2024年C、D卷真题集:最新的真题集题库 C/C++/Java/python/JavaScript
【华为OD】2024年C、D卷真题集:最新的真题集题库 C/C++/Java/python/JavaScript-CSDN博客
JS、C、Java、python、C++代码实现:
【华为OD】D卷真题100分:关联子串 JavaScript代码实现[思路+代码]-CSDN博客
【华为OD】D卷真题100分:关联子串 C语言代码实现[思路+代码]-CSDN博客
【华为OD】D卷真题100分:关联子串 java代码实现[思路+代码]-CSDN博客
【华为OD】D卷真题100分:关联子串 python代码实现[思路+代码]-CSDN博客
【华为OD】D卷真题100分:关联子串 C++代码实现[思路+代码]-CSDN博客
题目描述:
给定两个字符串str1和str2,如果字符串str1中的字符,经过排列组合后的字符串中,只要有一个字符串是str2的子串,则认为str1是str2的关联子串。
若str1是str2的关联子串,请返回子串在str2的起始位置;
若不是关联子串,则返回-1。
示例1:
输入:str1="abc",str2="efghicabiii"
输出:5
解释:str2包含str1的一种排列组合("cab"),此组合在str2的字符串起始位置为5(从0开始计数)
示例2:str1="abc",str2="efghicaibii"
输出:-1。
预制条件:
- 输入的字符串只包含小写字母;
- 两个字符串的长度范围[1, 100,000]之间
- 若str2中有多个str1的组合子串,请返回第一个子串的起始位置。
输入描述
输入两个字符串,分别为题目中描述的str1、str2。
输出描述
如果str1是str2的关联子串,则返回子串在str2中的起始位置。
如果str1不是str2的关联子串,则返回-1。
若str2中有多个str1的组合子串,请返回最小的起始位置。
示例1
输入输出示例仅供调试,后台判题数据一般不包含示例
输入
abc efghicabiii
输出
5
说明
str2包含str1的一种排列组合("cab"),此组合在str2的字符串起始位置为5(从0开始计数)
示例2
输入输出示例仅供调试,后台判题数据一般不包含示例
输入
abc efghicaibii
输出
-1
说明
“abc”字符串中三个字母的各种组合(abc、acb、bac、bca、cab、cba),str2中均不包含,因此返回-1
备注
输入的字符串只包含小写字母;
两个字符串的长度范围[1, 100,000]之间
34334
+---+
3 | | ++ + +---|
| | | 3 + 6 + | + | +
| + | | + + + | + | +
| + | +---+ + + +++++ + + + | +
| + | + | + +----+ | | + + + | +
| + 3 | + | + + + 2 | | 2 + + + | +
| + | + | + + + | | + + + | +
| +---+ + | | | + ----+ | +---+ | | + | +
| | + | | | + | | | | | | + | +
| 1 | + | 8 | | + 1 | | | 1 | | 1 | | + | +
| | + | | | + | | | | | | | + | +
| +---+ + +---+ | ++---+ ++ +---+ +---+ | + | +
| | + | | | ++ | | |+ | +
|0 | + | 0 | 0 | ++ | 0 | |+ | +
| | + | | | ++ | | |+ | +
+---+ + +-------+ +---+| +|+ | +
+ + | +
0 1 2 3 4 5 6 7 8 9 10 11 12 + v: w u m u 1 0 2 4
题目解析:
使用哈希表配合滑动窗口来实现即可
代码实现:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
int cnt1[26] = {0};
int cnt2[26] = {0};
void calcCnt(char *s1, char *s2, int len1, int pos) {
memset(cnt1, 0, sizeof(int) * 26);
memset(cnt2, 0, sizeof(int) * 26);
for (int i = 0; i < len1; i++) {
cnt1[s1[i] - 'a']++, cnt2[s2[pos + i] - 'a']++;
}
}
int calcEqual() {
for (int i = 0; i < 26; i++) {
if (cnt1[i] != cnt2[i]) {
return 0;
}
}
return 1;
}
int findOkPos(char *s1, char *s2) {
int len1 = strlen(s1);
int len2 = strlen(s2);
int pos = 0;
while (pos + len1 <= len2) {
calcCnt(s1, s2, len1, pos);
int isEqual = calcEqual();
if (isEqual) {
return pos;
}
pos++;
}
return -1;
}
int main() {
char *s1 = (char *) malloc(sizeof(char) * 1024 * 1024);
char *s2 = (char *) malloc(sizeof(char) * 1024 * 1024);
scanf("%s %s", s1, s2);
int ret = findOkPos(s1, s2);
printf("%d\n", ret);
return 0;
}