LeetCode 5. 最長迴文子串

来源:https://www.cnblogs.com/izhoujie/archive/2020/05/22/12939960.html
-Advertisement-
Play Games

我的LeetCode:https://leetcode cn.com/u/ituring/ 我的LeetCode刷題源碼[GitHub]:https://github.com/izhoujie/Algorithmcii LeetCode 5. 最長迴文子串 題目 給定一個字元串 s,找到 s 中最長 ...


我的LeetCode:https://leetcode-cn.com/u/ituring/

我的LeetCode刷題源碼[GitHub]:https://github.com/izhoujie/Algorithmcii

LeetCode 5. 最長迴文子串

題目

給定一個字元串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度為 1000。

示例 1:

輸入: "babad"
輸出: "bab"
註意: "aba" 也是一個有效答案。

示例 2:

輸入: "cbbd"
輸出: "bb"

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/longest-palindromic-substring
著作權歸領扣網路所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

解題思路

本題有三種思路解法:

  • dp動態規劃
  • 中心擴展
  • Manacher/馬拉車演算法

其中,前兩種時間複雜度都是\(O(n^{2})\),最後一種是\(O(n)\)的,目前最優解;

思路1-dp動態規劃

思路解析:dp的思路是若\([i] == [j]\),那麼讓\([i, j]\)是迴文就必須有\([i + 1] == [j - 1]\)
即dp的動態方程為:

\[dp[i, j] = dp[i + 1, j - 1] and ([i] == [j] || j - i < 3) \]

對於\(j - i < 3\)的解釋:當最後的只剩單個字元時,作為迴文的中心字元免驗證;

演算法複雜度:

  • 時間複雜度: $ {\color{Magenta}{\Omicron\left(n^{2}\right)}} $
  • 空間複雜度: $ {\color{Magenta}{\Omicron\left(n\right)}} $

思路2-中心擴展

思路解析:首先把字元串的所有連續相等的字元都壓縮看為一個字元,那麼對每一個字元嘗試左右擴展迴文長度即可;

核心思想:將所有連續相等的字元看為迴文的最中心字元,避免了對奇偶數的區別計算;

演算法複雜度:

  • 時間複雜度: $ {\color{Magenta}{\Omicron\left(n^{2}\right)}} $
  • 空間複雜度: $ {\color{Magenta}{\Omicron\left(1\right)}} $

思路3-Manacher/馬拉車演算法

待研究...

演算法複雜度:

  • 時間複雜度: $ {\color{Magenta}{\Omicron\left(n\right)}} $
  • 空間複雜度: $ {\color{Magenta}{\Omicron\left(n\right)}} $

演算法源碼示例

package leetcode;

/**
 * @author ZhouJie
 * @date 2019年12月10日 下午2:30:25 
 * @Description: 5. 最長迴文子串
 *
 */
public class LeetCode_0005 {

}

class Solution_0005 {
	/**
	 * @author ZhouJie
	 * @date 2019年12月10日 下午3:07:18 
	 * @Description: TODO(方法簡述) 
	 * @return String 
	 * @UpdateUser-UpdateDate:[ZhouJie]-[2019年12月10日 下午3:07:18]  
	 * @UpdateRemark:1-動態規劃
	 *
	 */
	public String longestPalindrome_1(String s) {
		int len = 0;
		if (s == null || (len = s.length()) < 2) {
			return s;
		}
		boolean[] p = new boolean[len];
		int[] range = new int[2];
		for (int i = len - 1; i >= 0; i--) {
			for (int j = len - 1; j >= i; j--) {
				// j-i考慮到 像OO和OHO最後中心的奇偶問題
				p[j] = s.charAt(i) == s.charAt(j) && (j - i < 3 || p[j - 1]);
				if (p[j] && (j - i > range[1] - range[0])) {
					range[0] = i;
					range[1] = j;
				}
			}
		}
		return s.substring(range[0], range[1] + 1);
	}

	/**
	 * @author ZhouJie
	 * @date 2019年12月10日 下午3:34:44 
	 * @Description: TODO(方法簡述) 
	 * @return String 
	 * @UpdateUser-UpdateDate:[ZhouJie]-[2019年12月10日 下午3:34:44]  
	 * @UpdateRemark:2-中心擴展--優化後
	 *
	 */
	public String longestPalindrome_2(String s) {
		if (s == null || s.length() < 2) {
			return s;
		}
		int[] range = new int[2];
		char[] cs = s.toCharArray();
		for (int i = 0; i < cs.length; i++) {
			// 把迴文看成中間部分都是同一字元且左右對稱,尋找下一個與當前字元不同的位置
			i = fastMove(cs, i, range);
			// 若剩餘長度不足已知最大長度的一半時,直接跳出迴圈
			// 剩餘長度的下一個起始計算位置為i+1,以為i+1為中心的剩餘最長迴文為(length-1-(i+1))*2+1
			// 即 (lenght-i-2)*2+1,一隻的最大長度為range[1]-range[0]+1
			// 所以判定條件為 (lenght-i-2)*2+1<range[1]-range[0]+1
			// 即(lenght-i-2)*2<range[1]-range[0]
			if ((cs.length - i - 2) * 2 < (range[1] - range[0])) {
				break;
			}
		}
		return s.substring(range[0], range[1] + 1);
	}

	private int fastMove(char[] cs, int low, int[] range) {
		int high = low;
		int len = cs.length;
		// 尋找下一個與low不等的字元
		while (high < len - 1 && cs[high + 1] == cs[low]) {
			high++;
		}
		int nextI = high;
		// 開始校驗左右擴散校驗
		while (low > 0 && high < len - 1 && cs[low - 1] == cs[high + 1]) {
			low--;
			high++;
		}
		if (high - low > range[1] - range[0]) {
			range[0] = low;
			range[1] = high;
		}
		return nextI;
	}

	/**
	 * @author: ZhouJie
	 * @date: 2020年5月22日 下午9:47:36 
	 * @param: @param s
	 * @param: @return
	 * @return: String
	 * @Description: 3-Manacher演算法--待研究
	 *
	 */
	public String longestPalindrome_3(String s) {
		return null;
	}
}



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 設計子程式 子程式一:在指定的位置,用指定的顏色,顯示一個用0結束的字元串 舉例:在屏幕的8行3列,用綠色顯示data段中的字元串 assume cs:code data segment db 'Welcome to masm!',0 data ends code segment start: mo ...
  • [TOC] QuantLib 金融計算——案例之普通利率互換分析(2) 概述 QuantLib 中涉及利率互換的功能大致分為兩大類: 對存續的利率互換合約估值; 根據利率互換合約的成交報價推算隱含的期限結構。 這兩類功能是緊密聯繫的,根據最新報價推算出的期限結構通常可以用來對存續合約進行估值。 本文 ...
  • 1 緩存導致的可見性問題 一個線程對共用變數的修改,另一個線程可以立即看到,這稱之為可見性。 Java記憶體模型規定所有的變數存儲在主記憶體中。每個線程都有自己的工作記憶體,線程在工作記憶體中保存了使用到的主記憶體中變數的副本拷貝,線程對變數的操作必須在工作記憶體中進行,不能直接讀寫主記憶體中的變數。不同線程之間 ...
  • 在項目中經常遇到需要動態編輯特定事物的一組屬性,這時就涉及到新選擇的值與舊值對比更新,記錄在項目中採用的一種方法,主要採用 PHP array_filter() 函數: $delete_array = $add_new_array = array(); $array1 = array( array( ...
  • 檢測是否存在JDK 接下來可以將 開頭的安裝包均卸載即可 下載JDK 在 /opt/soft 內下載jdk "AdoptOpenJDK" 解壓完之後, /opt/module/ ⽬錄中會出現⼀個 的⽬錄 配置JDK環境變數 編輯 ⽂件,在⽂件尾部加⼊如下 JDK 環境配置即可 然後執⾏如下命令讓環境 ...
  • 學習Django有一段時間了,最近剛好寫了一個小項目,用到了前後端交互,剛開始寫前後端交互確實很讓人頭暈目眩呢,下麵我來給大家介紹三種簡單的Django前後端交互的方法吧! 第一種 通過form表單的get或post請求提交到後端的請求方式 <form> <input type='text' nam ...
  • 聲明區域: 變數等可以聲明的區域 例:全局變數的聲明區域為其聲明所在的文件 潛在作用域: 從聲明點開始,到其聲明域的結尾 作用域: 變數對程式而言可見的範圍(即除去潛在作用域中被局部變數等隱藏的區域) ...
  • Hi,大家好,我是明哥。 在自己學習 Golang 的這段時間里,我寫了詳細的學習筆記放在我的個人微信公眾號 《Go編程時光》,對於 Go 語言,我也算是個初學者,因此寫的東西應該會比較適合剛接觸的同學,如果你也是剛學習 Go 語言,不防關註一下,一起學習,一起成長。 我的線上博客:http://g ...
一周排行
    -Advertisement-
    Play Games
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...