L2-008 最长对称子串

这道题可以用双指针解决。下面是我的解题思考:

1.首先最长重复某字符的子串肯定是对称的,例如...ssssffssBou...,毫无疑问ssss是对称的,所以第一步可以考虑寻找最长重复字符的子串。可以这么操作,我们将left指示ssss的起始位置,假设是i,则初始时left=i,right=i,然后right向右移动,判断right+1,right+2,right+3......是否和i位置的s相等

2.经过第一步后,此时right+1的字符和前面的最长重复字符不一样,按照上面的例子,ssss的下一个f不是s,此时我们right恰好指向ssss的最右端的s.

3.接着判断最长重复字符字符串左右两端的字符是否对称。即判断left-1和right+1,left-2和right+2,left-j和right+j是否对称

4.每轮获取到的最长长度即right-left+1,同时更新最终的最长长度即可。

C代码如下:

#include<stdio.h>
int main()
{
    char str[10001];
    char ch = '\0';
    int length = 0;
    //读取字符串
    while((ch = getchar()) != '\n')
    {
        str[length++] = ch;
    }
    str[length] = '\0';
    int i = 0;
    //start记录最长字符串的起始位置,end记录最长字符串的结束位置,本题不用输出,可以不用它们
    //但是如果需要指明最长对称字符串在哪里,它们是谁时,就会派上用场
    //int start = 0,end = 0;  
    int res = 0; //最长对称字符串的长度
    while(i < length)
    {
        int left = i,right = i;
        //寻找最长重复的字符的字符串,例如aaaaaabaaa,最长的就是aaaaa,到b停止
        //为什么这么操作?因为最长重复的字符的字符串它本身就是对称字符串
        //所以先找到左右不等的位置
        while(right + 1 < length && str[left] == str[right + 1])
        {
            ++right;
        }
        //找到以后呢?
        //此时的right是最长重复字符字符串的最右端,按上面的例子aaaaaabaaa
        //right是b,下面判断right右边的字符和left左边的字符是否也对称,即相等
        while(left > 0 && right + 1 < length && str[left - 1] == str[right + 1])
        {
            --left;
            ++right;
        }
        //此时left~right之间的字符串就是本次循环截取到的最长对称字符串
        //需要和上一次获得的结果进行比较,判断哪次是最长的
        int newMaxLength = right - left + 1;
        if(newMaxLength > res)
        {
            res = newMaxLength;
            //start = left;
            //end = right;
        }
        ++i;
    }
    printf("%d\n",res);
    return 0;
}

下面是java代码实现:

public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();
        int res = 0;
        int start = 0, end = 0;
        for (int i = 0; i < str.length(); i++) {
            int l = i, r = i;
            while (r + 1 < str.length() && str.charAt(r + 1) == str.charAt(i)) r++;
            while (l > 0 && r + 1 < str.length() && str.charAt(l - 1) == str.charAt(r + 1)) {
                l--;
                r++;
            }
            int newMaxLength = r - l + 1;
            if (newMaxLength > res) {
                res = newMaxLength;
                start = l;
                end = r;
            }
        }
        //最长对称子串的长度
        System.out.println(res);
        //输出这个最长对称子串
        System.out.println(str.substring(start, end + 1));
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值