Skip to content

Leetcode 1915. Number of Wonderful Substrings #236

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Woodyiiiiiii opened this issue Apr 13, 2023 · 0 comments
Open

Leetcode 1915. Number of Wonderful Substrings #236

Woodyiiiiiii opened this issue Apr 13, 2023 · 0 comments

Comments

@Woodyiiiiiii
Copy link
Owner

看到数组长度和有关substring,首先想到要用到O(n)时间复杂度,无关排序/堆之类的了。

那么选择就有滑动窗口、前缀和、动态规划、01背包等等解决方法,通过提前存储内容来解决重复问题(DP核心)

一时想不出来,说明还没吃透题意。题目要求最多有一个出现奇数次数的数,同时也限定了数的范围,非常小。显然后者是告诉我们要用固定长度的数组缓存。

继续观察,问题核心变成了奇偶出现次数,那么我们可以简化成01出现,进而可以用状态压缩表明了所有可能出现的状态。用1<<10表示,同时满足题意的状态只能是0和只有1个1的数(比如100...)。如此一来,列举所有目标状态,然后用异或运算来计算状态转换。

class Solution {
    public long wonderfulSubstrings(String word) {
        int[] cnt = new int[1 << 10];
        cnt[0] = 1;
        int mask = 0;
        long ans = 0;
        for (char c : word.toCharArray()) {
            mask ^= 1 << (c - 'a');
            // 0
            ans += cnt[mask];
            for (int b = 0; b < 10; ++b) {
                // 1
                ans += cnt[mask ^ (1 << b)];
            }
            ++cnt[mask];
        }
        return ans;
    }
}
func wonderfulSubstrings(word string) int64 {
    mask := 0
	count := make([]int, 1 <<10)
	count[0] = 1
	var ans int64
	for _, v := range word {
		mask ^= 1 << (v - 'a')
		ans += int64(count[mask])
		for i := 0; i < 10; i++ {
			ans += int64(count[mask ^ (1 << i)])
		}
		count[mask]++
	}
	return ans
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant