• 最长回文字符串计算


    定义:如果一个字符串正着读和反着读是一样的,那它就是回文串

       例如:aba 、 abba 不限制奇数偶数

    判断是否是回文字符串

      思路:从最前后各去一个做对比,如果相同则进行下一个,直到相挨为止

    function palindrome($str) {
    
        $i = 0;
        $j = strlen($str)-1;
    
        $flag = 1;
    
        while($i<$j)
        {
    
            if($str[$i] != $str[$j])
            {
                $flag = 0;
                break;
            }
    
            $i++;
            $j--;
    
        }
        
        return $flag;
        
    }

    计算最长回文字串

    方法1:

      暴力破解:计算出每个可能的字串,然后对比   

      时间复杂度:n(n^3)

    function findLongestPalindrome($str)
    {
        $palindrome = array();
        
        for($i=0;$i<strlen($str);$i++)
        {
            for($j=$i+1;$j<strlen($str);$j++)
            {
                $sub = substr($str, $i, $j-$i+1);
                if(palindrome($sub))
                {
                    $palindrome[] = strlen($sub);
                }
            }
        }
        
        return $palindrome ? max($palindrome) : 0;
        
    }

    方法2:中心扩展

    中心扩展就是把给定的字符串的每一个字母当做中心,向两边扩展,这样来找最长的子回文串。算法复杂度为O(N^2)。
    但是要考虑两种情况:
    1、像aba,这样长度为奇数。
    2、想abba,这样长度为偶数。

    function findLongestPalindrome($str)
    {
        $maxLen = 0;
        
        for($i=0;$i<strlen($str);$i++)
        {
            //奇数需要减1
            $left  = $i-(strlen($str)%2 == 0 ? 0 : 1);//左边走
            $right = $i+1;//右边走
            
            while($left>=0 && $right<strlen($str) && $str[$left] == $str[$right])
            {
                if($right-$left+1>$maxLen)
                {
                    $maxLen = $right-$left+1;
                }
                
                $left --;
                $right ++;
                
            }
        }
        
        return $maxLen;
        
    }

    方法3:Manacher

      1、奇偶数的问题,在字符串两边和中间分别插入特殊符号(如:#) 后,没个字符串都为奇数(奇数+偶数=奇数)

      2、重复访问问题,根据回文字符串的对称性快速扩展回文串

    function findLongestPalindrome($str)
    {
        //预处理,字符中间和两边增加#字符
        $strArr = str_split($str);    
        $str = '#'.implode('#', $strArr).'#';
        
        $maxLen = 0;
        
        $rl = array();//记录以该字符为中心的最长回文字符串半径
        $maxRight = 0;//现在访问到的最右边的字符
        $pos = 0; //$maxRight位置对应的轴位置
        
        for($i=0;$i<strlen($str);$i++)
        {
            if($i<$maxRight) //在左边
            {
                //根据回文串的对称性得出
                //应该为$pos-($pos-$i)],但最大不能超过 $maxRight-1 
                $rl[$i] = min($rl[$pos-($i-$pos)], $maxRight-1);
            }else{
                $rl[$i] = 1;
            }
            
            //向两边扩展 两边不能越界,且新的两边的字符还必须相等
            while($i-$rl[$i]>=0 && $i+$rl[$i]<strlen($str) && ($str[$i-$rl[$i]] == $str[$i+$rl[$i]]))
            {
                $rl[$i]++;
                
            }
            
            //更新 maxright,pos
            if($i+$rl[$i]-1>$maxRight)
            {
                $maxRight = $i+$rl[$i]-1;
                $pos = $i;
            }
            
            $maxLen = max($maxLen, $rl[$i]);
        }
        
        return $maxLen - 1;
    }

    参考:http://www.cnblogs.com/leoin2012/p/3984997.html

        https://segmentfault.com/a/1190000003914228

  • 相关阅读:
    margin:0 auto是什么意思
    CSS border-collapse 属性
    CSS-水平和垂直居中
    jQuery 事件
    移动端Html5控制布局
    CSS :root 测试
    SQL 读取XML到Datatable
    微信小程序 table 简单测试
    微信小程序 JS 获取View 和 屏幕相关属性(高度、宽度等等)
    JavaScript(正则表达式一)
  • 原文地址:https://www.cnblogs.com/siqi/p/6481672.html
Copyright © 2020-2023  润新知