回文数是正反读都是相同的数,如回文数 123321,正反读都是一样的,如回文字符串 “abccba”。
面试官常常会考回文数的编程题,今天小编分享两道关于回文数的面试题。
1. 求字符串中最大长度的回文字符串
如字符串“salksaffaskli”的最大回文字符串是“saffas”,字符串“kghifd”的最大回文字符串是 "k"(这里我设定为第一个)。
第一种方法采用暴力搜索法,通过两次循环并设置两个探头找到最大长度的回文字符串:
// 暴力破解
string palBrute(string str1)
{
// 字符串的长度
int l1 = str1.size();
// 回文字符串的最大长度
int maxLen = 1;
// 初始位置
int start = 0;
// 暴力搜索
for(int i =0;i < l1;i++)
for(int j=l1-1;j>i;j--)
{
int s1 = i;
int t1 = j;
while(str1[s1]==str1[t1] && s1<t1)
{
s1++;
t1--;
}
if(s1>=t1 && maxLen < j-i+1)
{
maxLen = j-i+1;
start = i;
}
}
return str1.substr(start,maxLen);
}
第二种方法是动态规划法,设置 dp[i][j]的含义为 索引i到索引j的字符串是否为回文字符串,因此递推关系可写为:
dp[i][j] = (dp[i] == dp[j] && dp[i+1][j-1])
编码:
// 动态规划,dp[i][j]表示索引i到j是否为回文字符串
string palDp(string str1)
{
//字符串长度
int l1 = str1.size();
//定义二维数组
vector<vector<int>> dp(l1,l1);
// 最大长度
int maxLen = 1;
// 定义初始点
int start = 0;
// 动态规划
for(int i = l1-1;i >= 0;i--)
for(int j =i;j < l1;j++)
{
if(j - i <= 1)
dp[i][j] = (str1[i]==str1[j]);
else
dp[i][j] = (str1[i]==str1[j] && dp[i+1][j-1]);
// 判断
if(dp[i][j] && maxLen < j-i+1)
{
// 更新初始点和最大长度
maxLen = j -i+1;
start = i;
}
}
return str1.substr(start,maxLen);
}
2. 检测某一个数是否为回文数
思路:我们依次从个位数到最大位数取数,并累加。
编码:
// 检查某一整数是否为回文数
bool palNum(int c1)
{
int t1= c1;
int d1 = c1%10;
if(d1==c1)
return true;
int sum1 = 0;
while(c1)
{
// 依次取数并累加
sum1 = sum1*10 + c1%10;
c1 = c1/10;
}
return (t1==sum1);
}
测试:
int main()
{
string str1;
while(cin>>str1)
{
string str2 = palDp(str1);
cout<<str2<<endl;
string str3 = palBrute(str1);
cout<<str3<<endl;
int c1,c2;
cin>>c1;
cout<< palNum(c1) << endl;
cin>>c2;
cout<< palNum(c2) << endl;
}
return 0;
}
结果:
欢迎扫码关注: