[Leedcode][JAVA][第5题][最长回文子串][数组][动态规划]
【問(wèn)題描述】[第5題][最長(zhǎng)回文子串][中等]
給定一個(gè)字符串 s,找到 s 中最長(zhǎng)的回文子串。你可以假設(shè) s 的最大長(zhǎng)度為 1000。示例 1:輸入: "babad" 輸出: "bab" 注意: "aba" 也是一個(gè)有效答案。【解答思路】
1. 中心擴(kuò)展法
時(shí)間復(fù)雜度:O(N^2) 空間復(fù)雜度:O(1)
2.暴力
- 根據(jù)回文子串的定義,枚舉所有長(zhǎng)度大于等于 22 的子串,依次判斷它們是否是回文;
- 在具體實(shí)現(xiàn)時(shí),可以只針對(duì)大于“當(dāng)前得到的最長(zhǎng)回文子串長(zhǎng)度”的子串進(jìn)行“回文驗(yàn)證”;
- 在記錄最長(zhǎng)回文子串的時(shí)候,可以只記錄“當(dāng)前子串的起始位置”和“子串長(zhǎng)度”
時(shí)間復(fù)雜度:O(N^3) 空間復(fù)雜度:O(1)
public class Solution {public String longestPalindrome(String s) {int len = s.length();if (len < 2) {return s;}int maxLen = 1;int begin = 0;// s.charAt(i) 每次都會(huì)檢查數(shù)組下標(biāo)越界,因此先轉(zhuǎn)換成字符數(shù)組char[] charArray = s.toCharArray();// 枚舉所有長(zhǎng)度大于 1 的子串 charArray[i..j]for (int i = 0; i < len - 1; i++) {for (int j = i + 1; j < len; j++) {if (j - i + 1 > maxLen && validPalindromic(charArray, i, j)) {maxLen = j - i + 1;begin = i;}}}return s.substring(begin, begin + maxLen);}/*** 驗(yàn)證子串 s[left..right] 是否為回文串*/private boolean validPalindromic(char[] charArray, int left, int right) {while (left < right) {if (charArray[left] != charArray[right]) {return false;}left++;right--;}return true;} }3. 動(dòng)態(tài)規(guī)劃
時(shí)間復(fù)雜度:O(N^2) 空間復(fù)雜度:O(N)
【總結(jié)】
1. 想法優(yōu)先暴力 逐漸優(yōu)化 不要東想西想
2.動(dòng)態(tài)規(guī)劃
1、思考狀態(tài)(重點(diǎn))
狀態(tài)的定義,先嘗試「題目問(wèn)什么,就把什么設(shè)置為狀態(tài)」;
然后思考「狀態(tài)如何轉(zhuǎn)移」,如果「狀態(tài)轉(zhuǎn)移方程」不容易得到,嘗試修改定義,目的依然是為了方便得到「狀態(tài)轉(zhuǎn)移方程」。
「狀態(tài)轉(zhuǎn)移方程」是原始問(wèn)題的不同規(guī)模的子問(wèn)題的聯(lián)系。即大問(wèn)題的最優(yōu)解如何由小問(wèn)題的最優(yōu)解得到。
2、思考狀態(tài)轉(zhuǎn)移方程(核心、難點(diǎn))
狀態(tài)轉(zhuǎn)移方程是非常重要的,是動(dòng)態(tài)規(guī)劃的核心,也是難點(diǎn);
常見(jiàn)的推導(dǎo)技巧是:分類討論。即:對(duì)狀態(tài)空間進(jìn)行分類;
歸納「狀態(tài)轉(zhuǎn)移方程」是一個(gè)很靈活的事情,通常是具體問(wèn)題具體分析;
除了掌握經(jīng)典的動(dòng)態(tài)規(guī)劃問(wèn)題以外,還需要多做題;
如果是針對(duì)面試,請(qǐng)自行把握難度。掌握常見(jiàn)問(wèn)題的動(dòng)態(tài)規(guī)劃解法,理解動(dòng)態(tài)規(guī)劃解決問(wèn)題,是從一個(gè)小規(guī)模問(wèn)題出發(fā),逐步得到大問(wèn)題的解,并記錄中間過(guò)程;
「動(dòng)態(tài)規(guī)劃」方法依然是「空間換時(shí)間」思想的體現(xiàn),常見(jiàn)的解決問(wèn)題的過(guò)程很像在「填表」。
3、思考初始化
初始化是非常重要的,一步錯(cuò),步步錯(cuò)。初始化狀態(tài)一定要設(shè)置對(duì),才可能得到正確的結(jié)果。
角度 1:直接從狀態(tài)的語(yǔ)義出發(fā);
角度 2:如果狀態(tài)的語(yǔ)義不好思考,就考慮「狀態(tài)轉(zhuǎn)移方程」的邊界需要什么樣初始化的條件;
角度 3:從「狀態(tài)轉(zhuǎn)移方程」方程的下標(biāo)看是否需要多設(shè)置一行、一列表示「哨兵」(sentinel),這樣可以避免一些特殊情況的討論。
4、思考輸出
有些時(shí)候是最后一個(gè)狀態(tài),有些時(shí)候可能會(huì)綜合之前所有計(jì)算過(guò)的狀態(tài)。
5、思考優(yōu)化空間(也可以叫做表格復(fù)用)
「優(yōu)化空間」會(huì)使得代碼難于理解,且是的「狀態(tài)」丟失原來(lái)的語(yǔ)義,初學(xué)的時(shí)候可以不一步到位。先把代碼寫正確是更重要;
「優(yōu)化空間」在有一種情況下是很有必要的,那就是狀態(tài)空間非常龐大的時(shí)候(處理海量數(shù)據(jù)),此時(shí)空間不夠用,就必須「優(yōu)化空間」;
非常經(jīng)典的「優(yōu)化空間」的典型問(wèn)題是「0-1 背包」問(wèn)題和「完全背包」問(wèn)題。
3. 動(dòng)態(tài)規(guī)劃思考
- 邊界問(wèn)題考慮清楚(第二第三步)
- 動(dòng)態(tài)就是做表格 想清楚方向
- 自底向上 子問(wèn)題 學(xué)基礎(chǔ) 再解決問(wèn)題 通識(shí)教育
- 自頂向下 一般解決問(wèn)題思路
轉(zhuǎn)載鏈接:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zhong-xin-kuo-san-dong-tai-gui-hua-by-liweiwei1419/
總結(jié)
以上是生活随笔為你收集整理的[Leedcode][JAVA][第5题][最长回文子串][数组][动态规划]的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 类818tu.c微信小说分销系统设计之定
- 下一篇: ssh配置文件详解