【leetcode】1177. Can Make Palindrome from Substring
题目如下:
Given a string
s
, we make queries on substrings ofs
.For each query
queries[i] = [left, right, k]
, we may rearrange the substrings[left], ..., s[right]
, and then choose up tok
of them to replace with any lowercase English letter.If the substring is possible to be a palindrome string after the operations above, the result of the query is
true
. Otherwise, the result isfalse
.Return an array
answer[]
, whereanswer[i]
is the result of thei
-th queryqueries[i]
.Note that: Each letter is counted individually for replacement so if for example
s[left..right] = "aaa"
, andk = 2
, we can only replace two of the letters. (Also, note that the initial strings
is never modified by any query.)
Example :
Input: s = "abcda", queries = [[3,3,0],[1,2,0],[0,3,1],[0,3,2],[0,4,1]] Output: [true,false,false,true,true] Explanation: queries[0] : substring = "d", is palidrome. queries[1] : substring = "bc", is not palidrome. queries[2] : substring = "abcd", is not palidrome after replacing only 1 character. queries[3] : substring = "abcd", could be changed to "abba" which is palidrome. Also this can be changed to "baab" first
rearrange it "bacd" then replace "cd" with "ab". queries[4] : substring = "abcda", could be changed to "abcba" which is palidrome.
Constraints:
1 <= s.length, queries.length <= 10^5
0 <= queries[i][0] <= queries[i][1] < s.length
0 <= queries[i][2] <= s.length
s
only contains lowercase English letters.
解题思路:对于给定一个query = [left,right,k],很容易能求出这个区间内每个字符出现的次数,如果某个字符出现了偶数次,那说明不需要经过任何改变,这个字符就能组成回文。所以这里只需要计算有多少个字符出现的次数是奇数,假设有x个字符出现的次数为奇数,那么至少就需要经过x/2次改变,才能形成回文。这里有一种情况例外,那就是只有一个字符出现的次数为奇数,那么可以不需要做任何改变。
代码如下:
class Solution(object): def canMakePaliQueries(self, s, queries): """ :type s: str :type queries: List[List[int]] :rtype: List[bool] """ grid = [[0] * len(s) for _ in range(26)] count = [0] * 26 for i,v in enumerate(s): for j in range(26): grid[j][i] = grid[j][i-1] inx = ord(v) - ord('a') count[inx] += 1 grid[inx][i] = count[inx] res = [] for left,right,k in queries: diff = 0 for i in range(26): if left > 0 and (grid[i][right] - grid[i][left-1]) % 2 != 0: diff += 1 elif left == 0 and grid[i][right] % 2 != 0: diff += 1 if diff == 1 or diff / 2 <= k: res.append(True) else: res.append(False) return res