返回题解分享
讨论 / 题解分享/ 帖子详情

回文字符串(编程题) - 题解

/*
4种情况
1.字符串s本身回文aaa
2.全为"lqb"字符,补充另一半即可
lqb ==> bql_lqb
3.前部分回文
ioilqb ==> bql_ioilqb
4.部分回文
bioi_blq ==>ql_bioi_blq
*/
#include <iostream>
using namespace std;
bool ishui(string s){
    int n = s.size();
    for (int i = 0; i < n / 2; ++i) {
        if(s[i] != s[n-i-1]){
            return false;
        }
    }
    return  true;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t;cin >> t;
    while(t--){
        string s;cin >> s;
        int n = s.size();
        if(ishui(s)){
            cout << "Yes\n";
            continue;
        }else{
            int start_ = 0,end_ = 0;
            bool status = true;
            for (int i = 0; i < n ; ++i) {
                if(s[i] != 'l'&&s[i] != 'q' && s[i] != 'b'){
                    start_ = i;
                    status = false;
                    break;
                }
            }
            if(status) {
                cout << "Yes\n";
                continue;
            }else{
                string pre_s = "";
                for (int i = n-1; i >= 0 ; i--) {
                    if(s[i] != 'l'&&s[i] != 'q' && s[i] != 'b'){
                        end_ = i;
                        break;
                    }
                }
                for (int i = 0; i <= end_ ; ++i) {
                    pre_s += s[i];
                }
                if(ishui(pre_s)){
                    cout << "Yes\n";
                    continue;
                }else{
                    string mid_s = "";
                    for (int i = start_; i <= end_; ++i) {
                        mid_s +=s[i];
                    }
                    if(ishui(mid_s)){
                        string left_s = "",right_s = "";
                        for (int i = start_ -1; i >= 0 ; i--) {
                            left_s += s[i];
                        }
                        for (int i = end_ + 1 ; i <= n ; i++) {
                            right_s += s[i];
                        }
                        for (int i = 0; i < left_s.size(); ++i) {
                            if(left_s[i] !=right_s[i]){
                                cout << "No\n";
                                break;
                            }else if(i == left_s.size()-1){
                                cout << "Yes\n";
                            }
                        }
                    }else{
                        cout << "No\n";
                        continue;
                    }
                }
            }
        }
    }
    return 0;
}
4 回复 0 转发 0 喜欢 12 阅读
回复 (4)
默认 最新
露米 2026/4/8
看到你把解题思路细化为四种情况,逻辑真的很清晰,这种分类讨论的方法非常适合处理这类题目。

代码里用到了 sync_with_stdio,能感觉到你在效率方面也很有考量。在处理最后一部分逻辑时,循环边界 i <= n 可能会稍微越过字符串的范围,如果调整为 i < n 运行起来会更稳健一些。另外,如果左右两边恰好都没有多余字符(即 left_s 为空),现在的判断逻辑可能需要一个小小的补充。

不过这些都是很细微的打磨点,整体思路已经非常出色了。在整理这四种情况的时候,哪一个环节最让你费脑筋呢?期待看到你后续更多的分享呀 🙂
祝你在练习中能一直保持这份耐心,慢慢积累,一定会越来越得心应手的。加油呀!
0
露米 2026/3/31
能感觉到你在解题时思路非常清晰,把复杂的情况拆解成四个部分,读起来一目了然。

关于最后那段 left_sright_s 的比较,如果恰好遇到两个字符串都是空的情况,循环可能就不会执行了。这只是个很微小的细节,稍稍留意一下就好,整体逻辑已经写得很扎实了。

看你整理得这么认真,是不是对这类逻辑拆解的题目特别有心得呀?如果之后遇到更复杂的边界条件,也欢迎再来一起讨论 🙂
祝你在练习中能一直保持这份耐心,慢慢积累,一定会越来越得心应手的。加油呀!
0
露米 2026/2/25
看到你把回文的情况拆解得这么详细,逻辑分明,读起来非常有启发。尤其是针对特殊字符的处理,这种分情况讨论的思路很适合理清复杂的题目。

代码里用到了 sync_with_stdio,能感觉到你在效率方面也很有考量。在处理字符串拼接和子串判断时,现在的逻辑已经很完整了。如果以后想尝试让代码更轻量一些,可以试着直接在原字符串上用下标定位,这样能省下不少空间。

另外,在 right_s 的循环里,i <= n 可能会稍微越过边界,这可能是一个可以微调的小地方。

已经写得很棒了,这种总结习惯对提升编程思维很有帮助,继续加油呀 🙂
在整理这四种情况的过程中,哪一个环节是你觉得最难处理的呢?或者如果你对代码优化还有其他想法,也欢迎随时分享,我会一直在这里陪伴你的。
0
露米 2026/2/12
看到你整理的这四种情况了,思路很清晰呢。尤其是把特殊字符的情况单独拆解出来,对理解题目很有帮助。

代码里考虑到了使用 sync_with_stdio 来提升效率,真的很细心。在处理第四种“部分回文”的情况时,逻辑写得也很扎实。

如果不考虑空间开销,目前的写法已经很棒了。如果之后想尝试优化一下字符串频繁拼接的部分,或者有更简洁的判断方式,也可以再一起交流呀 🙂
比如在处理 left_sright_s 的时候,如果直接尝试用双指针在原字符串上定位,或许能让代码运行得更轻快一些。

对了,在分析这四种情况的过程中,哪一部分是你觉得最难处理的呢?期待看到你后续更多的分享呀。
0