1. 程式人生 > >演算法設計與分析(5)-- Longest Palindromic Substring(難度:Medium)

演算法設計與分析(5)-- Longest Palindromic Substring(難度:Medium)

演算法設計與分析(5)

題目:Longest Palindromic Substring(最長的迴文字元子串)

問題描述: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”

Input: “cbbd”
Output: “bb”

演算法思路:

  1. 如果字串長度小於2,直接返回;

  2. 首先建立一個hash table(char, int),每個字元對應一個數值(由於這個例子中我們預設字元都是ASCII的,實際上直接使用每個字元的ASCII值, 沒有使用hash table);

  3. 建立vector<int> Index[256] ,這裡256對應每個ASCII字元,每個字元擁有一個vector,用來記錄這個字元出現的位置;

  4. 從字串頭部s[0]開始尋找最長的迴文字元子串,i 從0開始;由於我們已經有了vector<int> Index[256] 記錄了所有字元出現的位置;當我們來到s[i] ,我們直接尋找s[i] 這個字元出現在後面的所有位置,構成一個字元子串,逐個判斷能不能形成迴文字元子串;如果能形成迴文字元子串且其長度比原來記錄的更長,更新記錄的起始位置start, 結束位置end, 和長度length。
    對於結束條件可設定為s.length() - i > length

    , 因為當此條件成立,後面肯定不會出現比目前更長的迴文字元子串。

  5. 迴圈結束後返回最長的迴文字元子串。

實現程式碼:

#include<iostream>
#include<vector>
#include<string>

using namespace std;

bool isPalindromic(string &s, int i, int j)
{
    while (i <= j)
    {
        if (s[i] == s[j]) { ++i; --j;}
        else return false
; } return true; } string longestPalindrome(string s) { if (s.length() < 2) return s; int start = 0, end = 1, length = 1; vector<int> Index[256]; for (int i = 0; i < s.length(); ++i) Index[s[i]].push_back(i); for (int i = 0; s.length() - i > length; ++i) { for (int j = 1; j < Index[s[i]].size(); ++j) { if (Index[s[i]][j] > i && isPalindromic(s, i, Index[s[i]][j]) && (Index[s[i]][j] - i + 1) > length) { start = i; end = Index[s[i]][j]; length = end - start + 1; } } } string Palindrome(s.substr(start, length)); return Palindrome; } int main() { string s = "babad"; cout << longestPalindrome(s) << endl; return 0; }