笔试题7 – 对称之美
题目描述
给出n个字符串,从第1个字符串一直到第n个字符串每个串取一个字母来构成一个新字符串,新字符串的第i个字母只能从第i行的字符串中选出,这样就得到了一个新的长度为n的字符串,请问这个字符串是否有可能为回文字符串?
解题思路:
由于输入的单组案例中含有多个字符串,所以可以选择 vector 来存储单组输入中的所有字符串。
同时,结合题意得知最终需要合成的用于判断是否回文的字符串,是需要从每个输入字符串中各获取一个字符的,且位置需要与输入字符串的序号相对应,即假定合成的字符串为 result,则 result[i] 这个字符是只能从 vector[i] 这个字符串中取到的。
要想合成的字符串是回文的,那么字符串前后对称位置的相同字符必须在对应序号的输入字符串中可以取到。所以我们采用双指针的方式,规定 left 和 right 分别指向 vector 中的首尾字符串,两者在满足条件的情况下逐步向中心靠拢,直至相遇。
那么现在的问题变成了如何判断 left 和 right 所指向的两个字符串中是否有相同字符,于是我们想到用两个hash[26]表来存储两个字符串中各自分别出现过哪些字符,最后仅需要对哈希表同下标的值作判断即可得知两字符串中是否有相同字符。
示例代码:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
bool is_palindromic(const vector<string>& vs)
{
int size = vs.size();
int left = 0, right = size - 1;
while(left < right)
{
int hash_l[26] = {0};
int hash_r[26] = {0};
for(auto c: vs[left])
{
hash_l[c - 'a']++;
}
for(auto c: vs[right])
{
hash_r[c - 'a']++;
}
// 判断两字符串是否有相同字符
bool is_exist = false;
for(int i = 0; i < 26; i++)
{
if(hash_l[i] != 0 && hash_r[i] != 0)
{
is_exist = true;
break;
}
}
if(is_exist == false)
{
// 此时left和right对应的字符串已经没有相同字符,直接退出
return false;
}
left++;
right--;
}
return true;
}
int main()
{
int t = 0;
cin >> t;
while(t > 0)
{
int n = 0;
cin >> n;
vector<string> vs(n);
for(auto& s: vs)
{
cin >> s;
}
if(is_palindromic(vs))
{
cout << "Yes" << endl;
}
else
{
cout << "No" << endl;
}
t--;
}
return 0;
}
提交结果: