zoukankan      html  css  js  c++  java
  • 5.Longest Palindromic Substring

    给定一个字符串,求字符串中最长的回文子串。
    Input: "babad"
    Output: "bab"
    Note: "aba" is also a valid answer.

    思路:
    一、暴力解决,O(n^3) 的时间复杂度,最外层循环为 子串的起始位置,第二层循环为,对字符串中的字符遍历,若与子串的第一个字符相等,则停下来验证这一个子串是否是回文,第里层循环为回文验证。由于“bb……bb”这种字符串,第一次遍历后就得到了结果,不需要再进寻找,所以,需要对程序剪枝,尽量减小时间复杂度。虽然能AC,但时间复杂度还是太高了

    string longestPalindrome(string s) {
        string res = "" , tmp = "";
        for (int l = 0; l < (int)s.size(); l++) { //子串起始位置
            for (int i = l; i < (int)s.size(); i++) { //字符串遍历
                if (s[i] == s[l]) {
                    tmp = s.substr(l, i - l + 1);
                    int tmp_size = tmp.size(), flag = 1;
                    for (int j = 0; j < tmp_size/2; j++) { //回文判断
                        if (tmp[j] != tmp[tmp_size - 1 - j]) {
                            flag = 0;
                            break;
                        }
                    }
                    if (flag) res = tmp.size() > res.size() ? tmp : res;//更新结果
                }
            }
            if ((int)res.size() >= (int)(s.size() - l)) break;//剪枝
        }
        return res;
     }

    二、从中间往两边扩,时间复杂度O( n^2 ),但是要注意回文个数为奇数个、偶数个,偶数个的话必然中间至少有两个是相等的,比如 noon 中间的 oo相等,而奇数个的话,比如 aba ,可以不管 'b',下标l和r = b的下标,直接对比左边 l-1和右边 r+1的字符是否相等。所以,在处理偶数个时,将 oo 视为一个 O ,即:这儿需要保持 l 不变,将 r 向右移,noon可以看成  nOn,,然后当做奇数处理。

    string longestPalindrome(string s) {
        if (s.size() < 2) return s;
        string res = "";
        int n = s.size();
        for (int i = 0; i < n;) {
            int l = i, r = i;
            while (r < n - 1 && s[r] == s[r + 1]) r++;//处理偶数个,r右移
            i = r + 1;
            while (r < n - 1 && l>0 && s[r + 1] == s[l - 1]) {//处理奇数个
                l--;
                r++;
            }
            if ((int)res.size() < r - l + 1) res = s.substr(l, r - l + 1);
        }
        return res;
     }

    Java 版:

    class Solution {
        public String longestPalindrome(String s) {
            String res = "";
            for(int l = 0; l < s.length(); l++){
                for(int i = l; i < s.length(); i++){
                    if(s.charAt(l) != s.charAt(i)) continue;
                    String tmp = s.substring(l,i+1);
                    int n = tmp.length(), flag = 1;
                    for(int j = 0; j < n/2; j++){
                        if(tmp.charAt(j) != tmp.charAt(n-1-j)){
                            flag = 0;
                            break;
                        }
                    }
                    if(flag == 1) res = tmp.length() > res.length() ? tmp : res;
                }
                if(res.length() > s.length() - l) return res;
            }
            return res;
        }
    }

    第二种解法:

      • 使用中间向两边扩的思想;
      • 遇到 "baaaab" 这种情况,先跳过中间的 "aaaa",将 right指针移到最后一个 a 的下标,而 left 处于第一个 a 的下标,此时,开始 left、right 向两边扩,当 s.charAt(left) != s.charAt(right) 时,结束一轮循环;
      • 遍历完字符串 s 后,选择最长的一个作为答案。

    class Solution {
        public String longestPalindrome(String s) {
            char[] ch = s.toCharArray();
            String res = "";
            int left, right, n = ch.length;
            for(int i = 0; i < n; ){
                left = i; right = i;
                while(right < n - 1 && ch[right] == ch[right+1]) right++; // 跳过相同的字符
                i = right + 1 ; //下一次开始遍历的位置
                while(left > 0 && right < n - 1 && ch[left-1] == ch[right+1]){ //注意处理边界,0 和 n-1
                    left--; //中间像两边扩
                    right++;
                }
                if(res.length() < right-left+1) res = s.substring(left, right+1);
            }
            return res;
        }
    }
  • 相关阅读:
    GhostBSD 3.0RC3,基于GNOME的FreeBSD
    Nagios 3.4.3 发布,企业级监控系统
    Jolokia 1.0.6 发布, JMX远程访问方法
    微软希望开发人员不要使 WebKit 成为新版 IE6
    Kwort Linux 3.5 正式版发布
    EJDB 1.0.24 发布,嵌入式 JSON 数据库引擎
    Pale Moon 15.3 Firefox“苍月”优化版发布
    Galera Load Balancer 0.8.1 发布
    SmartSVN V7.5 正式发布
    PostgresQL建立索引如何避免写数据锁定
  • 原文地址:https://www.cnblogs.com/luo-c/p/12896551.html
Copyright © 2011-2022 走看看