美文网首页算法
1177. 构建回文串检测

1177. 构建回文串检测

作者: 红树_ | 来源:发表于2023-06-14 12:28 被阅读0次

LC每日一题,参考1177. 构建回文串检测,难度分1848。

题目

给你一个字符串 s,请你对 s 的子串进行检测。

每次检测,待检子串都可以表示为 queries[i] = [left, right, k]。我们可以 重新排列 子串 s[left], ..., s[right],并从中选择 最多 k 项替换成任何小写英文字母。

如果在上述检测过程中,子串可以变成回文形式的字符串,那么检测结果为 true,否则结果为 false

返回答案数组 answer[],其中 answer[i] 是第 i 个待检子串 queries[i] 的检测结果。

注意:在替换时,子串中的每个字母都必须作为 独立的 项进行计数,也就是说,如果 s[left..right] = "aaa"k = 2,我们只能替换其中的两个字母。(另外,任何检测都不会修改原始字符串 s,可以认为每次检测都是独立的)

输入:s = "abcda", queries = [[3,3,0],[1,2,0],[0,3,1],[0,3,2],[0,4,1]]
输出:[true,false,false,true,true]
解释:
queries[0] : 子串 = "d",回文。
queries[1] : 子串 = "bc",不是回文。
queries[2] : 子串 = "abcd",只替换 1 个字符是变不成回文串的。
queries[3] : 子串 = "abcd",可以变成回文的 "abba"。 也可以变成 "baab",先重新排序变成 "bacd",然后把 "cd" 替换为 "ab"。
queries[4] : 子串 = "abcda",可以变成回文的 "abcba"。

解题思路

  • 位集合+前缀和:直接使用哈希表对每个区间分开统计会超时,考虑使用前缀和,用位集合代替哈希表计数。

位集合+前缀和

class Solution {
    public List<Boolean> canMakePaliQueries(String s, int[][] queries) {
        char[] sc = s.toCharArray();
        //考虑使用前缀和优化区间计数
        int[] count = new int[sc.length+1];
        for(int i = 0; i < sc.length; i++) {
            //用位集合二进制表示26个不同字母 异或表示存储奇数为1偶数为0
            count[i+1] = count[i]^(1 << (sc[i]-'a')); 
        }
        List<Boolean> ans = new ArrayList<>();
        for(int[] q : queries) ans.add(check(count,q[0],q[1],q[2]));
        return ans;
    }

    boolean check(int[] count,int start,int end,int k) {
        //直接统计奇数个数的字母个数
        int hash = count[end+1]^count[start], cnt = 0;
        while(hash != 0) {
            cnt += hash & 1;
            hash >>= 1;
        }
        return cnt <= k*2 + (end-start+1)%2;
    }
}

复杂度分析

  • 时间复杂度:O(n+m)n为字符串长度,m为查询数组长度,前缀和统计n + 查询m,查询花费时间为常量级可忽略。
  • 空间复杂度:O(n),前缀和使用空间n

相关文章

网友评论

    本文标题:1177. 构建回文串检测

    本文链接:https://www.haomeiwen.com/subject/itahydtx.html