最长回文串的直球解法(JAVA)

本文介绍了一种解决最长回文串问题的直接方法,通过统计字符串中成对字符的数量来确定可能的最长回文串长度。文章详细解析了算法思路,包括区分大小写、统计字符出现次数及根据字符串长度的奇偶性判断回文串长度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


title: 最长回文串的直球解法
date: 2020-03-21 07:10:11
tags:

不得不说,你在尝试暴力解法的时候真的很直男

好吧,先把题目贴出来


给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars。
假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌握了这个单词。
注意:每次拼写时,chars 中的每个字母都只能用一次。
返回词汇表 words 中你掌握的所有单词的 长度之和。

我知道,绝对有人看到这个题目最先想的就是把这个字符串拆掉

没错我也是,嘿嘿(。。)

结果往往是一个百把行的代码还出现了Bug还不知道那里错了,难受 >_<

好吧不废话了,来点实在的


public static void main(String[] args) {
    String s = new String();
    s = "Bansanana";
    //提交算法
    final int N = 26;
    int[] Capital = new int[N]; //放大写字母
    int[] Lower = new int[N];   //放小写字母
    char[] Loge = new char[s.length()];
    int counst = 0,Fia = 0;

    Loge = s.toCharArray();  //拆分字符串
    
    //区分大小写,分开处理
    for(int i=0;i<s.length();i++){
        if(Loge[i] >= 'A' && Loge[i] <= 'Z')
            Capital[Loge[i] - 'A']++;  //统计出现次数
        if(Loge[i] >= 'a' && Loge[i] <= 'z')
            Lower[Loge[i] - 'a']++; 
    }

    //判断字符串的长度,分奇偶情况
    if(s.length() % 2 == 0){
    //偶数情况
        for(int i=0;i<N;i++){
            if(Capital[i] >= 2)
                counst = counst + Capital[i] / 2;  //统计成对的字符
        }
        for(int i=0;i<N;i++){
            if(Lower[i] >= 2)
                counst = counst + Lower[i] / 2;
        }

        //偶数情况下,如果成对的字符数*2和字符串的长度相对,那么这个字符串本身就是最长的回文串
        //否则,就说明这个字符串中有至少两个单独字符,随便拿一个出来组成回文串即可
        if(counst * 2 == s.length())
            Fia = s.length();
        else
            Fia = counst * 2 + 1;
    }
    else{
    //奇数情况
        //这一段的操作和上面一模一样的,可以直接烤过来
        for(int i=0;i<N;i++){
            if(Capital[i] >= 2)
                counst = counst + Capital[i] / 2;
        }
        for(int i=0;i<N;i++){
            if(Lower[i] >= 2)
                counst = counst + Lower[i] / 2;
        }
        //奇数情况从这里开始不同了
        //在奇数情况下,至少有一个字符注孤生
        //当只有一个单独字符时,说明这个字符串本身就是最长回文串(单独字符做中间字符)
        //否则,这个字符串就会有至少三个字符是单独字符,随便抽一个单独字符当中间字符即可构成回文串
        if(counst * 2 + 1 == s.length())
            Fia = s.length();
        else
            Fia = counst * 2 + 1;
    }

    System.out.println("\n");
    System.out.println(Fia);
}

}


我知道有很多人被那个超长的例子给拦住了,有相同经历的在心中扣个一OK?

大概解释一下思路

用两个数组分别存储大写字母和小写字母的出现次数,每个字母的出现次数默认为0,如果出现一次就在相应位置上加1

最后在确认长度时,只要将成对的字母提取出来,再根据总长度的奇偶情况判断即可求出题目所求
(具体操作写在代码注释里面)

总之,这个题目并不是要我们去拼合字符串而是需要我们去统计出成对的字符,回文串的长度只是一个顺带的操作

在网上还有很多大佬们写的高度简洁、精简的算法,大家可以去看看(我这个学JAVA还不到一个月的砸砸是着实看不懂)

在此感谢我家门口斗地主的老大爷们,就是他们给予了我灵感

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值