1177.can-make-palindrome-from-substring-cn
题目地址
https://leetcode.com/problems/can-make-palindrome-from-substring/
题目描述
思路
题中给出的字符串只包含小写字母(26个),让你判断给出的子串通过可重新排列和最多替换K个字母后,该子串是否可以组成回文字符串。
本题中,判断子串是否回文,有两个条件,
可重新排列,意思是只要子串中字母能组成回文即可不需要排好序的。 如:
abb
可以组成回文字符串bab
。本身不是回文,但可以重新排列成回文字符串。可最多替换K个字母,意思是本身或者通过从排列不能组成回文字符串,可以替换其中K个字母,也可以是回文字符串。 如:
abcd, k = 2
,可以替换cd -> ba
, 组成abba
。 或者是ab - dc
, 组成dccd
。 但如果abcd, k = 1
,无论如何替换,都不可能组成回文字符串。
通过分析,我们可以发现规律,只要计算出子串中有多少个数为奇数的字母 oddCounts
,如果oddCounts/2 >= K
, 则我们可通过替换将子串变成回文。 那么这题就变为如何快速的统计出区间出现次数为奇数的字母个数,区间个数,我们可以用前缀和个数统计。
为了快速统计区间个数,用前缀和数组
prefixCount[i][j]
记录前i
个字母中,字母j
出现的个数。统计区间
[start, end]
内出现的次数为奇数的字母个数oddCounts += prefixCount[end+1][currChar] - prefixcount[start][currChar]
。如果
oddCounts/2 >= K
, 则可以通过替换将子串变成回文。
如下图构建的前缀和数组prefixCount[i][j]
, 由于这里字符串只包含26个小写字母,所以近似常数时间复杂度。
复杂度分析
时间复杂度:
O(n + m * 26) - n is s length, m is queries length
空间复杂度:
O(n * 26) - n is s length, n * 26 prefixcount matrix
Note, 可以用HashMap,这样不用每次都扫描26个字母,只要扫描出现过的字母即可。
判断字符串是否是回文:
回文字符串的特点:正读和反渎都是一样。如madam,noon, 12321, aaaa
等。
判断回文方法:
第一种解法:直接reverse字符串,然后判断两字符串是否相同。
return s == reverse(s)
第二种解法:前后两个指针
(left, right)
,left
从0
开始,right
从字符串最后一个字符开始,满足条件(left < right)
比较s[left]
与s[right]
是否相同,相同,则继续下一个,
left往右移,left++
,right往左移,right--
不同,则直接
return false
。
关键点分析
前缀和数组计算前
i
个字母,j
字母出现的次数每一次query,扫描计算出次数为奇数的字母的个数,与
k
比较
代码 (Java/Python3
)
Java/Python3
)Java code
Python3 code (slow :( )
Last updated