题解 | 宝石手串
宝石手串
https://www.nowcoder.com/practice/9648c918da794be28575dd121efa1c50
C语言版本
主要思路:找两个相同字符之间的最短距离,存储在哈希表对应的字母转换成ascii码的下标里面,如果前面没找到,可以看看字符串首尾相连时存不存在最短距离。
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//思路是对了,但是数据太大超时,原来是每次找到相同字符没有break的原因导致超时
int main() {
//创建一个哈希表用来记录这个字符到下一个相同字符的最短距离好像就行了。可以
//如果找到最后位置没有找到相同,则从头开始找。ok肯定能实现,看看大佬们又没更好的算法。
int hash_count[26]; //-1表示这个字母没有出现或者没有另一个相同属性的宝石给他断
//memset(hash_count, -1, sizeof(hash_count));
int n;
scanf("%d\n",&n);
for(int i=1;i<=n;i++)
{
memset(hash_count, -1, sizeof(hash_count)); //每次使用都初始化
int l;
scanf("%d\n",&l);
char* string=malloc(sizeof(char)*(l+1));
scanf("%s",string);
for(int j=0;string[j]!='\0';j++)
{
bool isfind=false;//如果找到末尾都没找到可能存在环形的路径
for(int k=j+1;string[k]!='\0';k++)
{
if(string[j]==string[k]) //找到两个相同字符的距离
{
isfind=true; //找到了
if(hash_count[string[j]-'a']==-1) //没有出现过记录
{
hash_count[string[j]-'a']=k-j-1; //记录数据
}else {
if(k-j-1<hash_count[string[j]-'a']) //当前的距离是否比旧的记录少
{
hash_count[string[j]-'a']=k-j-1; //记录更少数据
}
}
break; //找到了就可以不用继续找了,应该是这个原因导致超时
}
}
//前面没找到,可以看看字符串首尾相连时存不存在最短距离。环形路径
if(isfind==false)
{
int mowei_l=l-1-j;//记录末尾的长度
for(int s=0;s<j-1;s++)
{
if(string[j]==string[s]) //找到从末尾开始的路径
{
if(hash_count[string[j]-'a']==-1) //没有出现过记录
{
hash_count[string[j]-'a']=mowei_l+s; //记录数据
}else {
if(mowei_l+s<hash_count[string[j]-'a']) //当前的距离是否比旧的记录少
{
hash_count[string[j]-'a']=mowei_l+s; //记录更少数据
}
}
break; //找到了就可以不用继续找了,应该是这个原因导致超时
}
}
}
}
//输出结果找最小
int min=l; //默认最长就是l
bool cunzai=false;//是否存在最小的路径
for(int i=0; i<26;i++)
{
//printf("%c=%d\n",i+'a',hash_count[i]);
if(hash_count[i]!=-1&&hash_count[i]<min)
{
cunzai=true;
min=hash_count[i];
}
}
if(cunzai==true)
{
printf("%d\n",min);
}else {
printf("%d\n",-1);
}
}
return 0;
}