Hi 你們好,我是張小豬。歡迎來到『寶寶也能看懂』系列之 leetcode 周賽題解。git
這裏是第 173 期的第 1 題,也是題目列表中的第 1332 題 -- 『刪除迴文子序列』github
給你一個字符串 s
,它僅由字母 'a' 和 'b' 組成。每一次刪除操做均可以從 s
中刪除一個迴文 子序列。shell
返回刪除給定字符串中全部字符(字符串爲空)的最小刪除次數。segmentfault
「子序列」定義:若是一個字符串能夠經過刪除原字符串某些字符而不改變原字符順序獲得,那麼這個字符串就是原字符串的一個子序列。spa
「迴文」定義:若是一個字符串向後和向前讀是一致的,那麼這個字符串就是一個迴文。code
示例 1:blog
輸入:s = "ababa" 輸出:1 解釋:字符串自己就是迴文序列,只須要刪除一次。
示例 2:leetcode
輸入:s = "abb" 輸出:2 解釋:"abb" -> "bb" -> "". 先刪除迴文子序列 "a",而後再刪除 "bb"。
示例 3:rem
輸入:s = "baabb" 輸出:2 解釋:"baabb" -> "b" -> "". 先刪除迴文子序列 "baab",而後再刪除 "b"。
示例 4:字符串
輸入:s = "" 輸出:0
提示:
0 <= s.length <= 1000
s
僅包含字母 'a' 和 'b'EASY
題目的意思很是的簡單,給定一個只由 'a' 和 'b' 這兩種字母組成的字符串,須要返回把該字符串刪空所需的最小次數。要求也只有一條,是每次刪除的是一個迴文子序列。
等等,what?excuse me?黑人問號臉...又是迴文字符串,又是最小次數,仍是 EASY 難度...嚇得小豬趕忙揉了揉眼睛,在確認沒看錯以後趕忙吃了一袋薯片壓壓驚...
想了想,發現沒有藉口再吃第二袋薯片了,因而決定仍是再看看題吧。發現題目中其實有一個很重要的信息,那就是每次能夠被移除的是一個迴文子序列。不是迴文子字符串,不是迴文子字符串,不是迴文子字符串!重要的事情說三編。湊字數
爲何我會說這一個信息很是重要呢,重要到直接回歸到了 EASY 的難度。下面咱們舉個例子吧:
如今我有一個原始字符串是 'aababbaabaabbabbaaabbabbbaabba'。那麼它的子字符串是什麼,就是截取其中連續的一串,例如 'babbaa'。而它的子序列是什麼呢,就是不打亂順序的從中隨意取出字符,湊成一串,例如 'aaaa'。
相信看到這裏,小夥伴們應該明白爲何說難度一會兒降到 EASY 了吧。雖然題目有要求是迴文子序列,但是若是個人子序列中只包含一種類型的字符,例如只包含 'a' 或者 'b',那不管長度是多少,都是迴文字符串了。再而後,原始字符串只由 'a' 和 'b' 這兩種字母組成。也就是說...其實咱們最多隻須要兩次就能夠刪空整個原始字符串了。
是否是很是的鵝妹子嚶!哈哈哈哈,機智的小豬又有藉口能夠吃薯片啦 >.<
上面咱們分析出瞭解題思路,以及最大的次數是 2。那麼具體什麼狀況下是 0、1 和 2 呢。
到了這一步,相信小夥伴們能夠輕鬆的給出實現流程了吧。具體以下:
基於這個流程,咱們能夠實現相似下面的代碼:
const removePalindromeSub = s => { if (s.length === 0) return 0; for (let left = 0, right = s.length - 1; left < right; ++left, --right) { if (s[left] !== s[right]) return 2; } return 1; };
固然咱們也能夠一行代碼來實現,只不過判斷迴文的邏輯須要作一點變化。也就是經過把原始字符串反序而後和自身比較來判斷是不是迴文字符串。具體一行實現的代碼以下:
const removePalindromeSub = s => s.length === 0 ? 0 : s.split('').reverse().join('') === s ? 1 : 2;
說實話最開始小豬是有被題目嚇到。由於按照慣例第一題應該是個送分題鴨,怎麼一上來就是迴文字符串什麼的。仔細看題以後才發現其中的玄機。正應徵了,魯迅曾經可能沒說過,『看題不仔細,作題兩行淚』。小夥伴們可不要學小豬這樣爲了吃薯片很差好看題鴨。
加油武漢,天佑中華