<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          每日一道 LeetCode (48):最長(zhǎng)回文子串

          共 517字,需瀏覽 2分鐘

           ·

          2020-09-17 16:18

          f6a9011ab47fb44b14409f4c05163aa9.webp

          ?

          每天 3 分鐘,走上算法的逆襲之路。

          ?

          前文合集

          每日一道 LeetCode 前文合集

          代碼倉(cāng)庫

          GitHub:https://github.com/meteor1993/LeetCode

          Gitee:https://gitee.com/inwsy/LeetCode

          題目:最長(zhǎng)回文子串

          難度:「中等」

          題目來源:https://leetcode-cn.com/problems/longest-palindromic-substring/

          給定一個(gè)字符串 s,找到 s 中最長(zhǎng)的回文子串。你可以假設(shè) s 的最大長(zhǎng)度為 1000。

          示例 1:

          輸入:?"babad"
          輸出:?"bab"
          注意:?"aba"?也是一個(gè)有效答案。

          示例 2:

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

          解題方案一:暴力解法

          暴力方案就很適合我這種腦子不夠用的人,首先把字符串中的所有子串取出來,當(dāng)然哈,取長(zhǎng)度大于 1 的子串,不然也沒啥意義。

          然后挨個(gè)判斷取出來的子串是否回文串,判斷完了以后取到最大的那個(gè),然后返回出來,結(jié)束。

          public?String?longestPalindrome(String?s)?{
          ????int?len?=?s.length();
          ????if?(len?2)?{
          ????????return?s;
          ????}
          ????//?先把字符串轉(zhuǎn)成數(shù)組
          ????char[]?charArray?=?s.toCharArray();
          ????//?定義初始位置
          ????int?left?=?0;
          ????//?定義字符串長(zhǎng)度
          ????int?length?=?1;
          ????//?獲取所有子串
          ????for?(int?i?=?0;?i?1;?i++)?{
          ????????for?(int?j?=?i?+?1;?j?????????????if?(j?-?i?+?1?>?length?&&?valid(charArray,?i,?j))?{
          ????????????????left?=?i;
          ????????????????length?=?j?-?i?+?1;
          ????????????}
          ????????}
          ????}
          ????return?s.substring(left,?left?+?length);
          }

          //?判斷是否回文串
          private?boolean?valid(char[]?charArray,?int?left,?int?right)?{
          ????while?(left?????????if?(charArray[left]?!=?charArray[right])?{
          ????????????return?false;
          ????????}
          ????????left++;
          ????????right--;
          ????}
          ????return?true;
          }
          21be47cea9113ce8950eb2f170cb46b4.webp

          這個(gè)答案慢肯定是慢,時(shí)間復(fù)雜度達(dá)到了 O(n^3) ,不慢才有鬼了。

          解題方案二:中心擴(kuò)散

          上面的方案是從兩邊開始往中間夾,中心擴(kuò)散的思想是從中間開始往兩邊進(jìn)行擴(kuò)散。

          我在答案中找到了一個(gè)非常形象的圖解,和大家分享一下:

          1f16bd9d509fef72f060a933ae8aa1d2.webp

          解釋一下這張圖,現(xiàn)在假設(shè)有一個(gè)字符串 「acdbbdaa」 ,從第一個(gè) b 位置開始找最長(zhǎng)回文串。

          • 首先往左尋找與當(dāng)期位置相同的字符,直到遇到不相等為止。
          • 然后往右尋找與當(dāng)期位置相同的字符,直到遇到不相等為止。
          • 最后左右雙向擴(kuò)散,直到左和右不相等。

          這時(shí)我們找到了從 b 開始最長(zhǎng)的回文子串,然后在程序中記錄下來。

          每一個(gè)位置開始都按這個(gè)方案去找最長(zhǎng)的回文子串,最后得到的結(jié)果就是最長(zhǎng)的回文子串。

          public?String?longestPalindrome_1(String?s)?{
          ????if?(s?==?null?||?s.length()?==?0)?return?"";

          ????int?length?=?s.length();
          ????//?定義左右指針
          ????int?left?=?0,?right?=?0;
          ????//?定義長(zhǎng)度
          ????int?len?=?1;
          ????//?定義最大開始位置和最長(zhǎng)子串長(zhǎng)度
          ????int?maxStart?=?0,?maxLen?=?0;
          ????for?(int?i?=?0;?i?????????left?=?i?-?1;
          ????????right?=?i?+?1;
          ????????//?計(jì)算左邊
          ????????while?(left?>=?0?&&?s.charAt(left)?==?s.charAt(i))?{
          ????????????len++;
          ????????????left--;
          ????????}
          ????????//?計(jì)算右邊
          ????????while?(right?????????????len++;
          ????????????right++;
          ????????}
          ????????//?兩邊一起擴(kuò)散
          ????????while?(left?>=?0?&&?right?????????????len?+=?2;
          ????????????left--;
          ????????????right++;
          ????????}
          ????????//?如果當(dāng)前長(zhǎng)度大于最大長(zhǎng)度
          ????????if?(len?>?maxLen)?{
          ????????????maxLen?=?len;
          ????????????maxStart?=?left;
          ????????}
          ????????//?下次循環(huán)前重置?len
          ????????len?=?1;
          ????}
          ????return?s.substring(maxStart?+?1,?maxStart?+?1?+?maxLen);
          }
          758d392698339d0b39db473f69138922.webp

          解題方案三:動(dòng)態(tài)規(guī)劃

          動(dòng)態(tài)規(guī)劃我的理解實(shí)際上就是一個(gè)把已經(jīng)判斷過的信息緩存起來的一種方案,很像我們?cè)谧?Web 開發(fā)的時(shí)候用到的 redis ,只是在答案中換成了一個(gè)矩陣或者說是二維數(shù)組。

          如果一個(gè)字符串 s[l, r] 是一個(gè)回文串,那么 s[l + 1, r - 1] 一定也是一個(gè)回文串,相當(dāng)于兩頭各去掉一個(gè)字符。

          如果這時(shí)我們直接通過某種方式直接可以知道 s[l + 1, r - 1] 是一個(gè)回文串,那么只需要判斷 s[i] 和 s[j] 相等就可以了。

          所以就有了下面的代碼:

          public?String?longestPalindrome_2(String?s)?{
          ????if?(s?==?null?||?s.length()?==?0)?return?s;
          ????int?length?=?s.length();
          ????int?maxStart?=?0;??//最長(zhǎng)回文串的起點(diǎn)
          ????int?maxEnd?=?0;????//最長(zhǎng)回文串的終點(diǎn)
          ????int?maxLen?=?1;??//最長(zhǎng)回文串的長(zhǎng)度

          ????//?定義一個(gè)布爾矩陣
          ????boolean[][]?dp?=?new?boolean[length][length];
          ????for?(int?r?=?1;?r?????????for?(int?l?=?0;?l?????????????if?(s.charAt(r)?==?s.charAt(l)?&&?(r?-?l?<=?2?||?dp[l?+?1][r?-?1]?==?true))?{
          ????????????????dp[l][r]?=?true;
          ????????????????if?(r?-?l?+?1?>?maxLen)?{
          ????????????????????maxLen?=?r?-?l?+?1;
          ????????????????????maxStart?=?l;
          ????????????????????maxEnd?=?r;
          ????????????????}
          ????????????}
          ????????}
          ????}
          ????return?s.substring(maxStart,?maxEnd?+?1);
          }
          09001026b93d00d2d32fb51159bafb1e.webp

          可以看到耗時(shí)也是蠻多的。

          答案中還給出了一種叫做 Manacher 算法的方案,原諒我比較菜,屬實(shí)是沒看懂,就不拿出來獻(xiàn)丑了。





          感謝閱讀f71f7bc0c205336dbeae451b077a5e62.webp



          瀏覽 34
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  青春草在线观看国产 | 免费鸡巴视频网站 | 日本黄色电影免费网站 | 欧美日韩国产VA在线观看免费 | 亚洲人成电影一区二区在线 |