LeetCode 系列 第5題

2021-03-02 堆了個棧

複習了一下第5題, 這篇文章Review一下思路和代碼

P0005

刷題地址: 

https://leetcode.com/problems/longest-palindromic-substring/

簡單描述:

Given a string s, return the longest palindromic substring in s.

難度指數: Medium

這道題比較經典, 常規思路就是動態規劃, 時間複雜度偏高,題目的意思翻譯過來就是最長回文子字符串。也是字符串搜索的一個經典題目。

先貼代碼

public class Solution {    public String longestPalindrome(String s) {        if (s.isEmpty()) {            return s;        }        int n = s.length();        boolean[][] dp = new boolean[n][n];        int maxLen = 1;        int begin = 0;        for (int i = 0; i < n; i++) {            dp[i][i] = true;        }        for (int j = 1; j < n; j++) {            for (int i = 0; i < j; i++) {                if (s.charAt(i) != s.charAt(j)) {                    dp[i][j] = false;                } else {                    if (j - i < 3) {                        dp[i][j] = true;                    } else {                        dp[i][j] = dp[i + 1][j - 1];                    }                }
if (dp[i][j] && (j - i + 1) > maxLen) { maxLen = j - i + 1; begin = i; } } } return s.substring(begin, begin + maxLen);    }}

因為是要返回最長回文子字符串, 所以需要確定起點和終點的位置,才能返回所需要的子串。

動態規劃,英文名叫Dynamic Programming。核心的要義是要確定狀態數組和狀態迭代中的推導關係。構造二維布爾類型數組, 行列對應起點和終點序號。 推導公式很明顯, 思路和代碼都比較清晰。

寫DP的時候時間複雜度基本不能達到最優, 比如這道題就是 O(n2)的時間複雜度, 因為計算狀態數組是二維的, 時間複雜度定死了。實際上我們在計算的過程中, 冥冥中會有一種感覺, 循環中的計算實際上感覺有點重複了。

這道題Wiki上面也是有記錄的:

https://en.wikipedia.org/wiki/Longest_palindromic_substring

使用馬拉車算法(Manacher's algorithm)可以達到線性複雜度, 效率上大大提升了。這個算法之後總結字符串中搜索的典型算法的時候總結一些, 這裡就不介紹了。刷題如果沒看過相關算法, 解法能達到線性複雜度的話,很好請收下我的膝蓋。 

Golang代碼如下, 重寫的時候優化了一下內部的邏輯,代碼稍微比Java優雅一些。

func longestPalindrome(s string) string {  if len(s) == 0 {    return ""  }    dp := make([][]bool, len(s))  for i := range dp {    dp[i] = make([]bool, len(s))  }  left, length := 0, 1  for j := 0; j < len(s); j++ {    dp[j][j] = true    for i := 0; i < j; i++ {      if j-i == 1 {        dp[i][j] = s[i] == s[j]      } else {        dp[i][j] = s[i] == s[j] && dp[i+1][j-1]      }      if dp[i][j] && j-i+1 > length {        length = j - i + 1        left = i      }    }  }  return s[left : left+length]}

相關焦點

  • 【SQL刷題系列】:leetcode180 Consecutive Numbers
    點擊上方 ↑ 藍色關注「Python數據科學」SQL刷題系列:SQL作為一種資料庫查詢和程序設計語言,是從事數據技術人員必備的技能,也是各大公司的數據分析、數據挖掘、資料庫等筆試題必考的一種題。為此,Python數據科學開啟了SQL刷題的系列,希望可以幫助有需要的朋友們。
  • LeetCode面試系列 第2天:No.136 - 只出現一次的數
    LeetCode面試題題系列的上一篇文章 Leetcode面試系列 第1天:Leetcode 89 - 格雷碼 中,我們介紹了
  • C#刷遍Leetcode面試題系列連載(2): No.38 - 報數
    前言前文傳送門:C# 刷遍 Leetcode 面試題系列連載
  • LeetCode面試系列 第5天:No.204 - 統計質數
    在上篇算法題的文章中,我們介紹了 LeetCode 中的一道數學題 -
  • C#刷遍Leetcode面試題系列連載(1) - 入門與工具簡介
    (TLE)5、Presentation Error. ——格式錯。程序沒按規定的格式輸出答案。(PE)6、Memory Limit Exceeded. ——超內存。程序沒在規定空間內出答案。(MLE)7、Compile Error. ——編譯錯。程序編譯不過。(CE)而在 LeetCode 中,應該是沒有第5種狀態的。
  • Leetcode題解 WordBreak
    上述將返回true,因為"leetcode"可以分割成"leet code".  由於本題每個組成成分都是單詞,也就是每次在原有字符串的返回true的基礎上增加一個字典中的單詞來組成新的能夠返回true的字符串.發現這是一種全局同一限制性的求解問題,限制條件是每次字符串增加的都是一個存在於字典中的單詞.舉個例子說明一下:  比如字符串是"leetcodeisnice
  • leetcode刷題最強指南(版本1.0)
    為什麼會有這篇刷題指南很多剛開始刷題的同學都有一個困惑:面對leetcode上近兩千道題目,從何刷起
  • LeetCode刷題第三周【數組(簡單)】
    第 k 個缺失的正整數(難度:簡單)Oct.28 刷題請點擊或見附錄:1539. 第 k 個缺失的正整數[3]題目要求:給你一個 嚴格升序排列 的正整數數組 arr 和一個整數 k 。示例 1:輸入:arr = [2,3,4,7,11], k = 5輸出:9解釋:缺失的正整數包括 [1,5,6,8,9,10,12,13,...] 。第 5 個缺失的正整數為 9 。
  • 【SQL刷題系列】:leetcode183 Customers Who Never Order
    (點擊上方藍色,快速關注)SQL刷題系列:SQL作為一種資料庫查詢和程序設計語言,是從事數據技術人員必備的技能
  • leetcode刷題指南之PatchingArray
    我們發現前兩個數能得到1 - 3的數, 發現第3個數是7 > 4, 故添加4, 則當前能得到1 - 7的數, 之後掃描到7, 發現7 < 8, 直接更新當前能得到的數位1 - 14, 故答案為1.
  • Leetcode刷題-動態規劃
    本文對leetcode上部分動態規劃問題進行分析並用python實現5. 最長回文子串 題目描述給定一個字符串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。整體代碼結構也是與第五題的動態規劃代碼類似。
  • 回溯法|一文解決四道 Leetcode「組合總和」題
    示例:輸入: candidates = [10,1,2,7,6,1,5], target = 8,所求解集為:[  [1, 7],  [1, 2, 5],  [2, 6],  [1, 1, 6]]>「leetcode-39.
  • Leetcode刷題-鍊表
    為了符合大多數人的習慣,本題從1開始計數,即鍊表的尾節點是倒數第1個節點。例如,一個鍊表有6個節點,從頭節點開始,它們的值依次是1、2、3、4、5、6。這個鍊表的倒數第3個節點是值為4的節點。示例:給定一個鍊表: 1->2->3->4->5, 和 k = 2.返回鍊表 4->5.
  • LeetCode面試系列 第4天:No.202 - 快樂數
    或許你不知道的是,Leetcode 中是有很多 數學題 的,本文要解析的題 快樂數 就是其中到一個典型問題,本題將基於數據結構
  • 一套代碼解決 Combination Sum 系列問題(LeetCode 39/40/216)
    本篇文章是習題篇,以 LeetCode 上的 Combination Sum 系列問題為例,用一套代碼解決系列問題,對每一題根據題目條件的不同做代碼的微調。在回溯法問題中,很多細微條件的不同就會導致代碼思路上出現變化。對於 Combination Sum 系列問題,我們要處理的條件有:下面將一一講解如何微調代碼來處理這些條件。
  • leetcode刷題指南之RussianDollEnvelopes
    比如,[[5,4],[6,4],[6,7],[2,3]]的答案是3,因為[2,3] => [5,4] => [6,7]2.但現在每個套娃有兩個維度(w,h),簡單的排序已經不可以了,對於樣例來說,排序後是[2,3],[5,4],[6,4],[6,7],[5,4]是不能放進[6,4]裡的。不過,我們也可以發現一個現象,就是排在後面的是顯然不可能放進前面裡的,也就是說,最終的答案一定是在排序後的數組中依次出現的,相當於是排序後的一個子序列。
  • LeetCode按照怎樣的順序來刷題比較好?
    分享一下身邊大神的刷題順序:如果你時間比較緊迫,為了找工作而刷題,我建議你先刷熱門推薦,一共兩百多道題。先刷熱題 HOT 100,再刷精選 TOP 面試題,之後刷其他的題。刷題方法:第一遍:可以先思考,之後看參考答案刷,結合其他人的題解刷。思考、總結並掌握本題的類型,思考方式,最優題解。第二遍:先思考,回憶最優解法,並與之前自己寫過的解答作比對,總結問題和方法。
  • leetcode刷題指南之shortestPalindrome
    1class Solution { 2public: 3string shortestPalindrome(string s) { 4    reverse (s.begin (), s.end ()); 5    string h = s;  6    reverse (h.begin (), h.end ()); 7    unsigned
  • 初級樹狀數組 leetcode 練習題
    分享幾個簡單的樹狀數組練習題。一、背景之前分享了《樹狀數組模板》和《離散化模板》,今天來看幾道練習題。
  • 平衡二叉樹 - leetcode 劍指offer系列
    題目難度: 簡單原題連結[1]今天繼續更新劍指 offer 系列, 老樣子晚上 6 點 45 分準時更新公眾號 每日精選算法題, 大家記得關注哦~ 另外在公眾號裡回復 offer 就能看到劍指 offer 系列當前連載的所有文章了題目描述輸入一棵二叉樹的根節點,判斷該樹是不是平衡二叉樹。