LeetCode Weekly Contest 152.

问题 1

题目链接

思路:从 1 到 n 质数和合数分别计数,结果为质数阶乘 * 合数阶乘 % MOD
复杂度:时间复杂度 O(n^2),空间复杂度 O(1)。

Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution:
def numPrimeArrangements(self, n: int) -> int:
def is_prime(n):
for i in range(2, n // 2 + 1):
if n % i == 0:
return False

return True

p = 0
c = 1
mod = 10 ** 9 + 7

for i in range(2, n+1):
if is_prime(i):
p += 1
else:
c += 1

return math.factorial(p) % mod * math.factorial(c) % mod

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution {
public:
bool prime(int n) {
if (n < 2)
return false;

for (int i = 2; i * i <= n; i++)
if (n % i == 0)
return false;

return true;
}
int numPrimeArrangements(int n) {
const int MOD = 1e9 + 7;
long long res = 1;

int p = 0;
int c = 1;

for (int i = 2; i <= n; i++){
if (prime(i)) {
p += 1;
} else {
c += 1;
}
}

for (int i = 1; i <= p; i++)
res = res * i % MOD;

for (int i = 1; i <= c; i++)
res = res * i % MOD;

return res;
}
};

问题 2

题目链接

解法:计算前缀和,每次去掉一个元素,加入一个元素。
复杂度:时间复杂度 O(n),空间复杂度 O(1)。

Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution:
def dietPlanPerformance(self, A: List[int], k: int,
lower: int, upper: int) -> int:
res = 0
n = len(A)

s = sum(A[:k])

if s > upper:
res += 1
elif s < lower:
res -= 1

for i in range(n-k):
s -= A[i]
s += A[i+k]

if s > upper:
res += 1
elif s < lower:
res -= 1

return res

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Solution {
public:
int dietPlanPerformance(vector<int>& A, int k, int lower, int upper) {
int res = 0;

int n = A.size();

int s = 0;

for (int i = 0; i < k; ++i){
s += A[i];
}

if (s > upper) {
res += 1;
} else if (s < lower) {
res -= 1;
}

for (int i = 0; i < n-k; i++){
s -= A[i];
s += A[i+k];

if (s > upper) {
res += 1;
} else if (s < lower) {
res -= 1;
}
}

return res;
}
};

问题 3

题目链接

解法:26 个字母出现个数用前缀哈希存储,查询和比较 key 的差异为 O(1),注意可以 rearrange,所以字母出现次数差异只保留 % 2 的值,最后对字符串奇偶长度做判断。

复杂度:时间复杂度 O(n),空间复杂度 O(n)。

Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution:
def canMakePaliQueries(self, s: str,
queries: List[List[int]]) -> List[bool]:
n = len(s)

f = [[0 for _ in range(n+1)] for _ in range(26)]

for c in range(26):
for i in range(n):
if s[i] == chr(ord('a') + c):
f[c][i+1] = f[c][i] + 1
else:
f[c][i+1] = f[c][i]
res = []

for q in queries:
l, r, k = q[0], q[1] + 1, q[2]
odd = 0

for c in range(26):
if (f[c][r] - f[c][l]) % 2 != 0:
odd += 1

res.append(odd <= 2 * k + 1);

return res

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
public:
vector<bool> canMakePaliQueries(string s,
vector<vector<int>>& queries) {
int n = s.size();
vector<vector<int>> freq(26, vector<int>(n + 1, 0));

for (int c = 0; c < 26; c++)
for (int i = 0; i < n; i++)
freq[c][i + 1] = freq[c][i] + (s[i] == 'a' + c ? 1 : 0);

vector<bool> answer;

for (vector<int> &query : queries) {
int l = query[0], r = query[1] + 1, k = query[2];

int odd = 0;

for (int c = 0; c < 26; c++)
if ((freq[c][r] - freq[c][l]) % 2 != 0)
odd++;

answer.push_back(odd <= 2 * k + 1);
}

return answer;
}
};

问题 4

题目链接
解法:参考寒神的解答。利用 26 位整数的 bit 存储是否包含某个字母状态(状态压缩),遍历 puzzles 中的元素,枚举包括第一个字母的所有子 string 组合,然后求和。

复杂度:时间复杂度 O(max(W, P)),空间复杂度 O(W)。

Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution:
def findNumOfValidWords(self, words: List[str],
puzzles: List[str]) -> List[int]:
count = collections.Counter()
for w in words:
m = 0
for c in w:
m |= 1 << (ord(c) - ord('a'))
count[m] += 1

res = []

for p in puzzles:
bfs = [1 << (ord(p[0]) - ord('a'))]
for c in set(p[1:]):
bfs += [m | 1 << (ord(c) - ord('a')) for m in bfs]
res.append(sum(count[m] for m in bfs))

return res

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class Solution {
public:
vector<int> findNumOfValidWords(vector<string>& words,
vector<string>& puzzles) {
unordered_map<int, int> count;

for (auto& w: words) {
int mask = 0;
for (auto& c : w)
mask |= (1 << (c - 'a'));
count[mask] ++;
}

vector<int> res;

for (auto& p : puzzles) {
vector<int> mask_p;
vector<int> mask_new;

mask_p.push_back(1 << (p[0] - 'a'));

for (int i = 1; i < p.size(); i++) {
mask_new = mask_p;
for (auto& m : mask_p) {
mask_new.push_back(m | (1 << (p[i] - 'a')));
}
mask_p = mask_new;
}

int cnt = 0;

for (auto& m : mask_p)
cnt += count[m];

res.push_back(cnt);
}

return res;
}
};

留言

2019-09-01