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;
说实话最开始小猪是有被题目吓到。由于按照惯例第一题应该是个送分题鸭,怎么一上来就是回文字符串什么的。仔细看题以后才发现其中的玄机。正应征了,鲁迅曾经可能没说过,『看题不仔细,作题两行泪』。小伙伴们可不要学小猪这样为了吃薯片很差好看题鸭。
加油武汉,天佑中华