AI智慧安防視訊平臺EasyCVR視訊突然播放不了的原因排查
馬拉車演算法主要是用來解決最長迴文串問題的演算法。
核心是利用迴文串的特性進行的搜尋優化
理解馬拉車演算法先要知道迴文串的特性:迴文串左右對稱,例:abba,aba等等都是迴文串
瞭解了迴文串的特性下面我們去一步步推匯出馬拉車演算法:
# 由上述示例可看出當迴文串長度為奇數時對稱中心在字串中的某個字元上,當迴文串為偶數時對稱中心在字串兩個相鄰字元之間。
一、最基本的演算法:
遍歷所有可能的對稱中心並找到以其為對稱中心的最長迴文串,找到所有遍歷中最長的迴文串。
該演算法的時間複雜度為O(n^2)
二、優化
當我們遍歷時需要考慮奇數和偶數的情況,為了方便,網上很多會在相鄰兩個字元間加入個無意義字串(很多都是使用#),這樣遍歷到#的時候其實就是相當於遍歷到對稱中心在字串兩個相鄰字元之間的這種情況,當然也可以不做此處理。
上述演算法有很多重複的搜尋,我們能否利用迴文串的特性對其進行優化,去掉不必要的搜尋?
答案是:可以
我們再回頭去看回文串的特性:左右對稱
由此作為根本進行延申推理,當我們遍歷的對稱中心a,在某個迴文串B中(B的對稱中心為b)時,其相對於b的對稱點為點c。有以下的結論。
1、當以c作為對稱中心的最長迴文串在B以內,則必定有以a為中心相同的一個迴文串
這種情況下有兩種情況
(1)以c作為對稱中心的最長迴文串沒有到達B迴文串的邊界
這種情況以a為中心的最長迴文串和以c為中心的最長迴文串相同,如圖所示:
(2)以c作為對稱中心的最長迴文串到達B迴文串的邊界
這種情況下,以a為中心的最長迴文串可能要比以c作為對稱中心的最長迴文串要長,所以需要接著找其最長迴文串,如圖所示:
2、當以c作為對稱中心的最長迴文串在B以外時,則當找尋以a為對稱中心的迴文串時,在在B內的部分則不需要再進行迴文串驗證,如圖所示:
三、優化後的演算法
class Solution { public String longestPalindrome(String s) { int newN = s.length() * 2 + 1; char[] cs = new char[newN]; int[] len = new int[newN]; for(int i = 0; i < s.length(); i++){ cs[i* 2] = '#'; cs[i * 2 + 1] = s.charAt(i); } cs[newN - 1] = '#'; int pc = 0, mx = 0, mxCenterPos = 0; len[0] = 0; for (int i = 1; i < cs.length; i++) { int rightBorderPos = pc + mx; if(i > rightBorderPos){ int pt = 1, leftPos = i - pt, rightPos = i + pt; while(rightPos < cs.length && leftPos >= 0){ if(cs[rightPos] != cs[leftPos]){ break; } pt++; leftPos--; rightPos++; } pc = i; mx = pt - 1; len[i] = mx; if(mx > len[mxCenterPos]){ mxCenterPos = i; } } else { int symmetricPoint = pc - (i - pc); if(len[symmetricPoint] >= pc + mx - i){ int pt = pc + mx - i + 1, leftPos = i - pt, rightPos = i + pt; while(rightPos < cs.length && leftPos >= 0){ if(cs[rightPos] != cs[leftPos]){ break; } pt++; leftPos--; rightPos++; } pc = i; mx = pt - 1; len[i] = mx; if(mx > len[mxCenterPos]){ mxCenterPos = i; } }else{ len[i] = len[symmetricPoint]; } } } int stIdx = (mxCenterPos - len[mxCenterPos]) / 2; int edIdx = (mxCenterPos + len[mxCenterPos]) / 2; return s.substring(stIdx, edIdx); } }