leetCode第五题 js实现

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

示例 2:

输入: "cbbd"
输出: "bb"

来源于LeetCode

可以直接跳过我写的代码,看大佬的代码,毕竟我写的代码太垃圾了!!!

最近做题的最大感触就是太依赖于其他的数据结构作为存储,然后使用它们的方法操作,比如数组的push,pop,还要对象作为存储,有时候还要删除对象里的某个属性,这样做大大的降低了性能,时间和内存消耗都是非常严重的,就是这样所以第一和第三题就不敢发出来。虽然今天的第五题内存消耗和时耗也不低,但是,我再贴一个LeetCode的题解里面大神的代码,这样比较更能让我在刷题的时候提示自己,不能过多的借用其他数据结构。

首先这题我的想法是

1.遍历s字符串

2.以每个字符为中心扩散判断是否有回文数

但是这要分为两种情况: 1.回文数是abba类型的,也就是说回文数的长度是偶数

                                         2.回文数是aba类型的,回文数的长度的奇数

因此每个字符要判断这两种情况(说实话这种想法有点糟糕,每个字符判断两种情况,而且还不算这个字符在两边扩散时候的情况,这也是消耗时间的,虽然很耗时,但是还是写下来,留给以后的自己看,不要再像这样了)

3.无论是奇数类型(arr2)的回文数还是偶数类型(arr1)的回文数都放入数组中,然后判断这两个数组到底哪个长,把长的赋给arr1

4.判断result的长度和arr1的长度 , 把最长的赋给result(说实话太麻烦了)

5.继续将中心转移到下一个字符

回文数是abba类型的

self表示所在的字符的索引 , left表示所在字符索引的左边。right表示在右边, length1表示在偶数方法的长度

             arr1 = []; //表示记录偶数字符串的
            arr2 = [];  //表示记录奇数字符串的
            length1 = 0;//偶数字符的长度初始值
            left = right = self; //最开始的时候left和right都指向self
            right ++;   //首先判断的是偶数情况,所以是应该要从两个字符向周围扩展,即 self 和self+1扩展
            while (s[left] == s[right] && left >= 0 && right < s.length) {//第一种情况,最长回文数是abba类型长度是偶数
                arr1.unshift(s[left]);//将左和右加入到arr1的数组中
                arr1.push(s[right]);
                right++;               //向两边扩散,在判断左右两边是否有相同的字符,持续下去直到没有相同的
                left--;
                length1 += 2;//回文数的数量每次成对出现
            }

奇数类型的

            left = self - 1;//重新将left和right置位
            right = self + 1;
            length2 = 1;         //因为奇数个的时候,所在的中心是回文数最中间的,所以直接将他的长度置为1,并且加入到arr2数组中
            arr2.push(s[self]);
            while (s[left] == s[right] && left >= 0 && right < s.length) { //和偶数的一样扩散
                arr2.unshift(s[left]);
                arr2.push(s[right]);
                right++;
                left--;
                length2 += 2;
            }

全部代码

var longestPalindrome = function (s) {
        let left, right, length1, length2, self = 1, result = [], arr1 , arr2;
        while (self < s.length) {
            arr1 = [];
            arr2 = [];
            length1 = 0;
            left = right = self;
            right ++;
            while (s[left] == s[right] && left >= 0 && right < s.length) {//第一种情况,最长回文数是abba类型长度是偶数的
            // console.log(s[left] + '  ' +s[right])
                arr1.unshift(s[left]);
                arr1.push(s[right]);
                right++;
                left--;
                length1 += 2;//回文数的数量每次成对出现
            }
            // console.log(arr1)
            //把left和right归位,判断是否有aba这种单数的
            left = self - 1;
            right = self + 1;
            length2 = 1;
            arr2.push(s[self]);
            while (s[left] == s[right] && left >= 0 && right < s.length) {
                arr2.unshift(s[left]);
                arr2.push(s[right]);
                right++;
                left--;
                length2 += 2;
                
                // console.log('我执行额' + length2 +' ' + self)
            }
            // console.log(length1 + ' ' + length2)
           arr1 = arr1.length > arr2.length ? arr1 : arr2;
           result = arr1.length > result.length ? arr1 : result;
            self ++;
        }
        return result.join('');
    };

 

 

大佬的代码(用c写的)

介绍一下大佬的思路

首先连续重复的字符一定能构成回文子串  ,如aaabb('aaa' , ‘bb’)   cdbbbbdbv('bbbb')

只要我们记住重复的字符串的开始和结尾,再以最后一个重复的字符为重心扩展 ,如aaabb , 记住第一个a的初始位置

 

 

char * longestPalindrome(char * s){
  int left = 0;
    int right = 0;    
    int maxLength = 0;      //回文子串最大长度
    int startIndex = 0;     //最长回文子串开始位置
    int index = 0;

    while(s[index]){
        right=index;
        left=index-1;
    
        //从当前字符开始往右读取连续重复字符(连续重复字符必定能构成回文子串,也必定是回文子串的一部分)
        //如"abcccd" 中从索引1开始的连续重复字符是"b",从索引2开始连续重复字符是'ccc'
        while(s[right]==s[index]){
            right++;
        }

        //定位下一个子串的中心
        index = right;
        
        //以连续重复字符为中心,往左右延展,判断当前子串是否为回文子串
        while(left >= 0 && s[right] && s[left]==s[right]){
            left--;
            right++;
        }
        
        //记录回文子串的最大长度和起始索引
        if(right-left-1>maxLength){
            startIndex = left+1;
            maxLength = right-left-1;
        }
     
    }
    
    //返回回文子串
    char* returnStr = (char*)malloc(maxLength+1);
    returnStr[maxLength]='\0';
    for(int i=0;i<maxLength;i++){
        returnStr[i]=s[startIndex+i];
    }
    return returnStr;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值