题目来源:牛客
[编程题] 数组中两个字符串的最小距离
题目描述:
给定一个字符串数组 strs ,再给定两个字符串 str1 , str2 ,返回在 strs 中 str1 和 str2 的最小距离,如果 str1 或 str2 为 null ,或不在 strs 中,返回 -1 。
输入描述:
输入包含有多行,第一行输入一个整数 n (1 ≤ n ≤ 105) ,代表数组 strs 的长度,第二行有两个字符串分别代表 str1 和 str2 ,接下来 n 行,每一行一个字符串,代表数组 strs (保证题目中出现的所有字符串长度均小于等于 10 )。
输出描述:
输出一行,包含一个整数,代表返回的值。
示例1
输入:1
CD AB
CD
输出:-1
说明:strs 数组为[“CD”],由于"AB"不在 strs 里,返回 -1
示例2
输入:5
QWER 666
QWER
1234
qwe
666
QWER
输出:1
说明:strs 数组为[“QWER”,“1234”,“qwe”,“666”,“QWER”],其中"QWER"和"666"的最短距离为 1(选择第四个和第五个字符)
解析
这题有两个解法:①暴力枚举,两成循环遍历,找出每个 str1 和 str2 之间的距离,求出最小值。但由于这一题数据量是 105 级别,两次循环肯定是要超时的,所以这里就不实现了。②贪心,我们使用贪心只需要一层遍历就可以找出最小值。我们遍历到 str1 或 str2 时,用变量存这个位置之前,并且最近的 str2 或 str1 的下标,相减就是当前的距离,直到遍历完,找出最小距离。
代码实现
#include<iostream> #include<string> using namespace std; int main() { int n; string str1, str2; string strs; cin >> n; cin >> str1 >> str2; // 记录 str1 的下标 int prev1 = -1; // 记录 str2 的下标 int prev2 = -1; // 记录答案,初始为答案不可能达到的最大值 int ans = 1e5 + 10; // 每次遍历与后面的数据无关,所以可以读一个判断一下 for (int i = 0; i < n; ++i) { cin >> strs; // 如果遍历到的值为 str1 ,则去前面找最近的 str2 if (strs == str1) { // 前面出先过 str2 if (prev2 != -1) { // 找到小值 ans = min(ans, i - prev2); } // 更新 str1 的下标 prev1 = i; } else if (strs == str2) { if (prev1 != -1) { ans = min(ans, i - prev1); } prev2 = i; } } // 根本没有更新答案,说明没有结果 if (ans == 1e5 + 10) { cout << -1; } cout << ans; return 0; }