在一个字符串里面怎么找出最长回文子序列长度

回文字符串是什么?类似于level,noon,abbba这种,就是从左读和从右读都是同一个字符串。。。。

先说一下我的思路:

比如现在有字符串:”12212321“

1,先在每个字符间隔的地方放一个“#”,这样做的目的是为了不用对字符串进行奇偶的分类讨论,这个字符串变成“#1#2#2#1#2#3#2#1#”;

2,把“#1#2#2#1#2#3#2#1#”变成一个字符数组;

3,开始遍历这个字符数组:

        (1)i 表示当前字符的下标,定义两个变量,toLeft表示从当前下标开始向左移动的下标,toRight表示从当前下表开始向右移动的下标;

        (2)定义一个boolean变量 find,表示在toLeft和toRight移动过程中是否已经找到最长的回文子字符串,定义一个radio的int变量表示回文子字符串的半径;

        (3)定义一个和字符串一样长度的int数组radios存放已每个字符为中心的回文子序列的最大半径;

        (4)toLeft向左移动的同时toRight向右移动,判断toLeft对应字符和toRight对应字符是否相等,如果相等半径就加1,不相等表示已经找到最长回文子字符串,把radio 放进radios数组;

        (5)如果找到回文子字符串,find = true;

        (6)toLeft和toRight在移动中要保证不能越界;

4,具体代码

package com.lin.test;

public class Huiwen {
    
    public static void main(String[] args) {
        System.out.println("12212321--------------------"+new Huiwen().maxHuiwen("12212321"));
    }
    
    private int maxHuiwen(String str){
        
        char[] chars = str.toCharArray();
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append('#');
        for(int i=0;i<chars.length;i++){
            stringBuilder.append(chars[i]);
            stringBuilder.append('#');
        }
        
        char[] temp = stringBuilder.toString().toCharArray();
        
        int[] radios = new int[temp.length];//存放当前字符为中心的构成回文字符串的最大半径

        for(int i=0;i<temp.length;i++){
            
            boolean find = false;//在当前字符中,是否已经找到以当前字符为中心的回文字符串
            int toLeft = i;
            int toRight = i;
            int radio = 1;//半径
            
            while(!find){
                
                toLeft --;//左移
                toRight++;//右移
                if(toLeft < 0 || toRight > temp.length - 1){//如果越界,跳出
                    break;
                }
                if(temp[toLeft] == temp[toRight]){
                    radio ++;//半径+1
                }
                else {
                    find = true;
                }
            }
            radios[i] = radio;
        }
        
        /**
         * 找出radios中最大值就是最长子序列长度
         */
        
        for (int i = 0; i < temp.length; i++) {
            System.out.print(temp[i]+"\t");
        }
        System.out.println();
        
        int max = -1;
        for(int i=0;i<radios.length;i++){
            System.out.print(radios[i]+"\t");
            if(radios[i] > max){
                max = radios[i];
            }
        }
        System.out.println();
        return max;
    }

}


5,运行结果

#    a    #    c    #    b    #    c    #    a    #    a    #    c    #    b    #    c    #    d    #    
1    2    1    2    1    6    1    2    1    2    9    2    1    2    1    4    1    2    1    2    1   

可以看到最长的半径是9,那么该字符串的最长回文子序列长度就是9-1=8;

转载于:https://my.oschina.net/ChiLin/blog/668864

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值