Manacher 算法_NOTACK

重要圖片

在這裏插入圖片描述

源代碼

int Manacher()
{
	int len = Init();  // 取得新字符串長度並完成向 s_new 的轉換
	int max_len = -1;  // 最長迴文長度
	int id;  // 以id中心的最長迴文
	int mx = 0; // b邊界
for (int i = 1; i < len; i++)
{
	// 如果i在列表右邊界內,那麼就比較i的對稱點j 和mx-i 的大小
	if (i < mx)
		p[i] = min(p[2 * id - i], mx - i);  
	else
		p[i] = 1;
	
	while (s_new[i - p[i]] == s_new[i + p[i]])  // 不需邊界判斷,因爲左有'$',右有'\0'
		p[i]++;//無法使用if (i < mx)來判斷,只能比較i兩邊的對應值是否相等
		
	// 我們每走一步 i,都要和 mx 比較,我們希望 mx 儘可能的遠,
	// 這樣才能更有機會執行 if (i < mx)這句代碼,從而提高效率
	
	if (mx < i + p[i])  // 超過mx邊界的i+p[i],邊界mx 需要重新賦值
		{
			id = i;
			mx = i + p[i];
		}
		
	max_len = max(max_len, p[i] - 1);  // 通過比較每個元素的p[i]和max_len的大小,更新max_len的值
}
	return max_len;
}

代碼分析

  • p[i] = min(p[2 * id - i], mx - i);mx-i 和 2*id-i是爲了防止i和j 的向左右擴展 ???會不會同時向兩邊擴展

Shoulders of Giants

一文讀懂迴文子串 Manacher 算法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章