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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...