zoukankan      html  css  js  c++  java
  • leetcode5- Longest Palindromic Substring- medium

    Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

    Example:

    Input: "babad"
    
    Output: "bab"
    
    Note: "aba" is also a valid answer.
    

    Example:

    Input: "cbbd"
    
    Output: "bb"

    1. O(n3)复杂度做。双层for循环,每次重新调用这个substring是不是palindrome的方程。

    2.O(n2)复杂度做。DP。boolean dp[i][j]定义为s.substring(i, j + 1)是不是回文串。状态转移方程是:dp[i][j] = s.charAt(i) == s.charAt(j) && (j - i < 3 || dp[i + 1][j - 1]); 

    细节:1.不用担心i+1, j-1超过范围,因为i,j能进for循环说明满足要求了,而且i比j小,所以i+1最大到j,j-1最小到i,都是合格的。 2.需要担心i+1, j-1之间出现交叉,避免方式就是加上j-i < 3的限制,当两者靠的足够近有交叉的风险的时候你就去人工认可。3.注意最后返回的字符串是s.substring(i, j+1)不是i,j。

    3.中心枚举法。O(n2)。对于每个子串的中心(可以是一个字符,或者是两个字符的间隙,比如串abc,中心可以是a,b,c,或者是ab的间隙,bc的间隙)往两边同时进行扫描,直到不是回文串为止。假设字符串的长度为n,那么中心的个数为2*n-1(字符作为中心有n个,间隙有n-1个)。对于每个中心往两边扫描的复杂度为O(n),所以时间复杂度为O((2*n-1)*n)=O(n^2),空间复杂度为O(1), 空间复杂度比DP的O(n2)要好。

    2.DP实现

    class Solution {
        public String longestPalindrome(String s) {
            if (s == null || s.length() == 0) {
                return "";
            }
            boolean[][] dp = new boolean[s.length()][s.length()];
            int ll = Integer.MIN_VALUE;
            int[] index = new int[2];
            // the problem is  caused when i and j are too close and i + 1 may cross with j - 1, but if they are close enough we can
            // just say by ourself. i==j, true, i + 1 == j, true, i + 2 == j, true
            // dp[i][j] = s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1];
            for (int i = s.length() - 1; i >= 0; i--) {
                for (int j = i; j < s.length(); j++) {
                    dp[i][j] = s.charAt(i) == s.charAt(j) && (j - i < 3 || dp[i + 1][j - 1]);
                    if(dp[i][j] && j - i > ll) {
                        ll = j - i;
                        index[0] = i;
                        index[1] = j;
                    }
                }
            }
            return s.substring(index[0], index[1] + 1);
        }
        
    }

    3.枚举法实现

    public class Solution {
        public String longestPalindrome(String s) {
            if (s == null || s.length() == 0) {
                return "";
            }
            
            int start = 0, len = 0, longest = 0;
            for (int i = 0; i < s.length(); i++) {
                len = findLongestPalindromeFrom(s, i, i);
                if (len > longest) {
                    longest = len;
                    start = i - len / 2;
                }
                
                len = findLongestPalindromeFrom(s, i, i + 1);
                if (len > longest) {
                    longest = len;
                    start = i - len / 2 + 1;
                }
            }
            
            return s.substring(start, start + longest);
        }
        
        private int findLongestPalindromeFrom(String s, int left, int right) {
            int len = 0;
            while (left >= 0 && right < s.length()) {
                if (s.charAt(left) != s.charAt(right)) {
                    break;
                }
                len += left == right ? 1 : 2;
                left--;
                right++;
            }
            
            return len;
        }
    }
  • 相关阅读:
    说明因 Active Directory 冲突导致的 NTDS 复制警告 ID 1083 和 1061 以及 SAM 错误 ID 12294
    KB817701:可用于解决帐户锁定问题的 Service Pack 和修复程序
    log check
    AD account 锁定问题
    VS.2005 中比较有用的快捷键
    用户帐户意外锁定, 以及 Windows Server 2003 中记录事件 ID 12294
    xp 重新安装MDAC
    [学习收藏]业界三种架构优缺点比较
    [收藏学习]Linux内核虚拟机 学习KVM架构及其优点
    两个命令:hdparm和iozone参数解释
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7947781.html
Copyright © 2011-2022 走看看