leetcode 笔记No.5

leetcode No.5 最长回文子串

自己只会暴力破解,贴两个题解的代码,当作整理

三个指针,一个左移的指针,一个右移指针,一个中心指针一直右移
1、初始化 r = l = index
2、把index和r+1的位置进行比较如果相等,则把r++,同时中心指针也右移 //如abbbbc的情况
3、无法再右移了,则进行由中心像两侧扩展,l-1,r+1进行对比判断,知道不成立为止。
4、记录最大值对应的起始地址和大小。

char * longestPalindrome(char * s){
    int len = 0;
    int index = 0;
    int maxLen = 1;
    int start = 0;
    int left, right;
    char *str = NULL;

    len = strlen(s);
    while(index < len - 1) /* 当index位于最后一个字符位置的时候不用考虑,因为此时最大为1 */
    {
        right = left = index;
        while(s[right + 1] == s[index++]) /* 如abbbbc的情况,中心右移 */
        {
            if (++right == len - 1)
            {
                break;
            }
        }
        while ((left > 0) && (left < len - 1) && (s[left - 1] == s[right + 1]))
        {
            left--;
            right++;
        }
        if (right - left + 1 > maxLen)
        {
            maxLen = right - left + 1;
            start = left;
        }
    }
    str = malloc(maxLen + 1);
    strncpy(str, s + start, maxLen);
    str[maxLen] = '\0';

    return str;
}
har * longestPalindrome(char * s){
    ///  默认最大回文串是第一个字符组成的长度为1的回文串
    ///  长度不超过1k,所以用16位储存即可。
    int16_t maxStart = 0, maxSize = 1; 
    int16_t s_len;
    int16_t start = 0, size = 2, left, right, i;

    for(s_len = 0;s[s_len];s_len++); ///< 计算长度
    if(s_len == 1) return s; ///< 长度为1则直接返回原字符串

    ///  start作为最长回文字符的中心,显然如果当前记录的最长回文为
    ///  maxSize位,那么第(s_len - (maxSize+1)/2 - 1)后的所有位都不可能
    ///  存在更长的回文.
    for(;start < (s_len - (maxSize+1)/2);start++)
    {
        ///  只检测比记录中更长的回文。
        ///  最简单的,尝试以start为中心,判断比记录长度多1或者2的回文需
        ///  要满足条件。
        ///  多2的条件下,左右指针的设置
        left = start - (maxSize + 1) / 2;
        right = start + maxSize / 2 + 1;
        if(left>=0&&s[right]==s[left]) ///< 验证最外层是否满足回文条件
        {
            ///  如果满足,检查内部是否满足条件
            for(left++, right--;s[right]==s[left]&&left<right;left++,right--);
            ///  如果内部满足要求,检查外部是否支持更长的回文
            if(left>=right)
            {
                maxStart = start - (maxSize+1) / 2;
                maxSize += 2;
                left = maxStart - 1;
                right = maxStart + maxSize;
                while(left>=0&&right<s_len&&s[right]==s[left])
                {
                    maxSize += 2;
                    maxStart--;
                    left--;
                    right++;
                }
            }
        }
        ///  多1的条件下,左右指针的设置。
        left = start - maxSize/2;
        right = start + (maxSize + 1) / 2;
        if(left>=0&&s[right]==s[left]) ///< 验证最外层是否满足回文条件
        {
            ///  如果满足,检查内部是否满足条件
            for(left++, right--;s[right]==s[left]&&left<right;left++,right--);
            ///  如果内部满足要求,检查外部是否支持更长的回文
            if(left>=right)
            {
                maxStart = start - maxSize/2;
                maxSize += 1;
                left = maxStart - 1;
                right = maxStart + maxSize;
                while(left>=0&&right<s_len&&s[right]==s[left])
                {
                    maxSize += 2;
                    maxStart--;
                    left--;
                    right++;
                }
            }
        }
    }
    
    s[maxStart+maxSize] = 0;
    return &s[maxStart];
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值