0%

力扣周赛301-

在今年寒假改完论文后,做了一个决定,就是在条件允许的情况下参加力扣周赛。只是做自己想做的事,语言用回C++吧。希望自己能够在其中得到成长。

Weekly Contest 301

image-20220710174532073

2335. Minimum Amount of Time to Fill Cups

You have a water dispenser that can dispense cold, warm, and hot water. Every second, you can either fill up 2 cups with different types of water, or 1 cup of any type of water.

You are given a 0-indexed integer array amount of length 3 where amount[0], amount[1], and amount[2] denote the number of cold, warm, and hot water cups you need to fill respectively. Return the minimum number of seconds needed to fill up all the cups.

Example 1:

1
2
3
4
5
6
7
8
Input: amount = [1,4,2]
Output: 4
Explanation: One way to fill up the cups is:
Second 1: Fill up a cold cup and a warm cup.
Second 2: Fill up a warm cup and a hot cup.
Second 3: Fill up a warm cup and a hot cup.
Second 4: Fill up a warm cup.
It can be proven that 4 is the minimum number of seconds needed.

Example 2:

1
2
3
4
5
6
7
8
9
10
Input: amount = [5,4,4]
Output: 7
Explanation: One way to fill up the cups is:
Second 1: Fill up a cold cup, and a hot cup.
Second 2: Fill up a cold cup, and a warm cup.
Second 3: Fill up a cold cup, and a warm cup.
Second 4: Fill up a warm cup, and a hot cup.
Second 5: Fill up a cold cup, and a hot cup.
Second 6: Fill up a cold cup, and a warm cup.
Second 7: Fill up a hot cup.

Example 3:

1
2
3
Input: amount = [5,0,0]
Output: 5
Explanation: Every second, we fill up a cold cup.

Constraints:

  • amount.length == 3
  • 0 <= amount[i] <= 100

Easy,这题我理了很久才想明白三个数的关系,静下心来,不要被自己的第一想法所左右

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public:
int fillCups(vector<int>& amount) {
sort(amount.begin(), amount.end());
int res = amount[1] - amount[0];
amount[1] -= res;
amount[2] -= res;
// cout<<amount[2]<<endl;

int k = amount[2] / 2, m = amount[2] % 2;
if (amount[0] < k) {
return amount[2] + res;
} else if (amount[0] == k) {
return res + 2 * k + m;

} else {
amount[0] -= (k + m);
amount[1] -= k;
// cout<<res<<k<<m<<amount[1];
return res + 2 * k + m + amount[1];

}
}
};

其实很简单的问题

1
2
3
4
5
6
7
8
9
10
11
class Solution {
public:
int fillCups(vector<int>& amount) {
int mx = 0, sum = 0;
for(int& num: amount) {
mx = max(num, mx);
sum += num;
}
return max(mx, (sum + 1) / 2);
}
};

2336. Smallest Number in Infinite Set

You have a set which contains all positive integers [1, 2, 3, 4, 5, ...].

Implement the SmallestInfiniteSet class:

  • SmallestInfiniteSet() Initializes the SmallestInfiniteSet object to contain all positive integers.
  • int popSmallest() Removes and returns the smallest integer contained in the infinite set.
  • void addBack(int num) Adds a positive integer num back into the infinite set, if it is not already in the infinite set.

Example 1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Input
["SmallestInfiniteSet", "addBack", "popSmallest", "popSmallest", "popSmallest", "addBack", "popSmallest", "popSmallest", "popSmallest"]
[[], [2], [], [], [], [1], [], [], []]
Output
[null, null, 1, 2, 3, null, 1, 4, 5]

Explanation
SmallestInfiniteSet smallestInfiniteSet = new SmallestInfiniteSet();
smallestInfiniteSet.addBack(2); // 2 is already in the set, so no change is made.
smallestInfiniteSet.popSmallest(); // return 1, since 1 is the smallest number, and remove it from the set.
smallestInfiniteSet.popSmallest(); // return 2, and remove it from the set.
smallestInfiniteSet.popSmallest(); // return 3, and remove it from the set.
smallestInfiniteSet.addBack(1); // 1 is added back to the set.
smallestInfiniteSet.popSmallest(); // return 1, since 1 was added back to the set and
// is the smallest number, and remove it from the set.
smallestInfiniteSet.popSmallest(); // return 4, and remove it from the set.
smallestInfiniteSet.popSmallest(); // return 5, and remove it from the set.

Constraints:

  • 1 <= num <= 1000
  • At most 1000 calls will be made in total to popSmallest and addBack.

Medium,我是使用栈

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
class SmallestInfiniteSet {
stack<int> stk;
public:
SmallestInfiniteSet() {
stk.push(1);
}

int popSmallest() {
int res = stk.top();
stk.pop();
if (stk.size() == 0) stk.push(res + 1);
return res;
}

void addBack(int num) {
stack<int> tmp;
while (stk.size() && stk.top() < num) {
tmp.push(stk.top());
stk.pop();
}
if (stk.size() > 0) {
if (stk.top() > num) {
stk.push(num);
}
}
while (tmp.size()) {
stk.push(tmp.top());
tmp.pop();
}
}
};

/**
* Your SmallestInfiniteSet object will be instantiated and called as such:
* SmallestInfiniteSet* obj = new SmallestInfiniteSet();
* int param_1 = obj->popSmallest();
* obj->addBack(num);
*/

或者用优先队列/set也可以解决,下面是使用priority_queueQQ

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
class SmallestInfiniteSet {
public:
priority_queue<int, vector<int>, greater<int>>q;
unordered_map<int, bool>m;
SmallestInfiniteSet() {
// 插入1000个数到容器中,并更新map
for(int i = 1; i <= 1000; i++) {
q.push(i);
m[i] = true;
}

}

int popSmallest() {
int a = q.top();
q.pop();
m[a] = false; // map记录这个数字为空
return a;
}

void addBack(int num) {
// 如果字典存在这个数字,但为空,插入
if (m.count(num)) {
if(m[num] == false) q.push(num);
m[num]=true;
} else { // 容器没这个数字,直接插入
q.push(num);
m[num] = true;
}
}
};

/**
* Your SmallestInfiniteSet object will be instantiated and called as such:
* SmallestInfiniteSet* obj = new SmallestInfiniteSet();
* int param_1 = obj->popSmallest();
* obj->addBack(num);
*/

使用set

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
class SmallestInfiniteSet {
public:
set<int>s;
SmallestInfiniteSet() {
s.clear();
for(int i = 1; i <= 1010; i++) s.insert(i);
}

int popSmallest() {
int x = *s.begin();
s.erase(s.begin());
return x;
}

void addBack(int num) {
s.insert(num);
}
};

/**
* Your SmallestInfiniteSet object will be instantiated and called as such:
* SmallestInfiniteSet* obj = new SmallestInfiniteSet();
* int param_1 = obj->popSmallest();
* obj->addBack(num);
*/

2337. Move Pieces to Obtain a String

You are given two strings start and target, both of length n. Each string consists only of the characters 'L', 'R', and '_' where:

  • The characters 'L' and 'R' represent pieces, where a piece 'L' can move to the left only if there is a blank space directly to its left, and a piece 'R' can move to the right only if there is a blank space directly to its right.
  • The character '_' represents a blank space that can be occupied by any of the 'L' or 'R' pieces.

Return true if it is possible to obtain the string target by moving the pieces of the string start *any number of times*. Otherwise, return false.

Example 1:

1
2
3
4
5
6
7
Input: start = "_L__R__R_", target = "L______RR"
Output: true
Explanation: We can obtain the string target from start by doing the following moves:
- Move the first piece one step to the left, start becomes equal to "L___R__R_".
- Move the last piece one step to the right, start becomes equal to "L___R___R".
- Move the second piece three steps to the right, start becomes equal to "L______RR".
Since it is possible to get the string target from start, we return true.

Example 2:

1
2
3
4
Input: start = "R_L_", target = "__LR"
Output: false
Explanation: The 'R' piece in the string start can move one step to the right to obtain "_RL_".
After that, no pieces can move anymore, so it is impossible to obtain the string target from start.

Example 3:

1
2
3
Input: start = "_R", target = "R_"
Output: false
Explanation: The piece in the string start can move only to the right, so it is impossible to obtain the string target from start.

Constraints:

  • n == start.length == target.length
  • 1 <= n <= 105
  • start and target consist of the characters 'L', 'R', and '_'.

Medium,L和R数量一致,每个L和R相对位置一致,L只能向左,R只能向右

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 canChange(string start, string target) {
int lNum = 0, rNum = 0;
vector<int> lPos, rPos;
vector<int> lRight, rLeft;
int n = start.size();
for (int i = 0; i < n; i++) {
if (start[i] == 'L') {
lPos.push_back(i);
lRight.push_back(rNum);
lNum++;
} else if (start[i] == 'R') {
rPos.push_back(i);
rLeft.push_back(lNum);
rNum++;
}
}
lNum = 0, rNum = 0;
for (int i = 0; i < n; i++) {
if (target[i] == 'L') {
if (lNum >= lPos.size()) return false;
if (i > lPos[lNum]) return false;
if (lRight[lNum] != rNum) return false;
lNum++;
} else if (target[i] == 'R') {
if (rNum >= rPos.size()) return false;
if (i < rPos[rNum]) return false;
if (rLeft[rNum] != lNum) return false;
rNum++;
}
}
if (lNum != lPos.size() || rNum != rPos.size()) return false;
return true;
}
};

双指针遍历2个字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public:
bool canChange(string start, string target) {
int i = 0, j = 0, n = start.length();
while(i < n && j < n){
while(i < n && start[i++] == '_');
while(j < n && target[j++] == '_');
i--;
j--;
if (start[i] != target[j]) return false;
if (start[i] == 'L') {
if (i < j) return false;
}
if (start[i] == 'R') {
if (i > j) return false;
}
i++;
j++;
}
return true;
}
};

Failed: 2338. Count the Number of Ideal Arrays

You are given two integers n and maxValue, which are used to describe an ideal array.

A 0-indexed integer array arr of length n is considered ideal if the following conditions hold:

  • Every arr[i] is a value from 1 to maxValue, for 0 <= i < n.
  • Every arr[i] is divisible by arr[i - 1], for 0 < i < n.

Return the number of distinct ideal arrays of length n. Since the answer may be very large, return it modulo 109 + 7.

Example 1:

1
2
3
4
5
6
7
8
9
Input: n = 2, maxValue = 5
Output: 10
Explanation: The following are the possible ideal arrays:
- Arrays starting with the value 1 (5 arrays): [1,1], [1,2], [1,3], [1,4], [1,5]
- Arrays starting with the value 2 (2 arrays): [2,2], [2,4]
- Arrays starting with the value 3 (1 array): [3,3]
- Arrays starting with the value 4 (1 array): [4,4]
- Arrays starting with the value 5 (1 array): [5,5]
There are a total of 5 + 2 + 1 + 1 + 1 = 10 distinct ideal arrays.

Example 2:

1
2
3
4
5
6
7
8
9
10
Input: n = 5, maxValue = 3
Output: 11
Explanation: The following are the possible ideal arrays:
- Arrays starting with the value 1 (9 arrays):
- With no other distinct values (1 array): [1,1,1,1,1]
- With 2nd distinct value 2 (4 arrays): [1,1,1,1,2], [1,1,1,2,2], [1,1,2,2,2], [1,2,2,2,2]
- With 2nd distinct value 3 (4 arrays): [1,1,1,1,3], [1,1,1,3,3], [1,1,3,3,3], [1,3,3,3,3]
- Arrays starting with the value 2 (1 array): [2,2,2,2,2]
- Arrays starting with the value 3 (1 array): [3,3,3,3,3]
There are a total of 9 + 1 + 1 = 11 distinct ideal arrays.

Constraints:

  • 2 <= n <= 104
  • 1 <= maxValue <= 104

Hard,小于maxValue的所有数分解质因数,再进行计算

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
class Solution {
const int MOD = 1000000007;
vector<long long> inv;

// O(b) 求组合数
long long C(int a, int b) {
if (b > a) return 0;
long long ret = 1;
for (int i = 1; i <= b; i++) ret = (ret * (a - i + 1) % MOD * inv[i]) % MOD;
return ret;
}

public:
int idealArrays(int n, int K) {
// nlnn 进行质因数分解,f[i] 的元素表示 i 的每种质因数的指数
vector<vector<int>> f(K + 1);
int mx = 0;
for (int i = 2; i <= K; i++) if (f[i].empty()) for (int j = i; j <= K; j += i) {
int x = j, y = 0;
for (; x % i == 0; x /= i) y++;
f[j].push_back(y);
mx = max(mx, y);
}

// 线性求逆元
inv.resize(mx + 5);
inv[1] = 1;
for (int i = 2; i <= mx; i++) inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;

// 统计答案
long long ans = 0;
for (int i = 1; i <= K; i++) {
long long t = 1;
for (int x : f[i]) t = (t * C(n + x - 1, x)) % MOD;
ans = (ans + t) % MOD;
}
return ans;
}
};

Weekly Contest 302

image-20220718090303244

2341. Maximum Number of Pairs in Array

You are given a 0-indexed integer array nums. In one operation, you may do the following:

  • Choose two integers in nums that are equal.
  • Remove both integers from nums, forming a pair.

The operation is done on nums as many times as possible.

Return a 0-indexed integer array answer of size 2 where answer[0] is the number of pairs that are formed and answer[1] is the number of leftover integers in nums after doing the operation as many times as possible.

Example 1:

1
2
3
4
5
6
7
Input: nums = [1,3,2,1,3,2,2]
Output: [3,1]
Explanation:
Form a pair with nums[0] and nums[3] and remove them from nums. Now, nums = [3,2,3,2,2].
Form a pair with nums[0] and nums[2] and remove them from nums. Now, nums = [2,2,2].
Form a pair with nums[0] and nums[1] and remove them from nums. Now, nums = [2].
No more pairs can be formed. A total of 3 pairs have been formed, and there is 1 number leftover in nums.

Example 2:

1
2
3
4
Input: nums = [1,1]
Output: [1,0]
Explanation: Form a pair with nums[0] and nums[1] and remove them from nums. Now, nums = [].
No more pairs can be formed. A total of 1 pair has been formed, and there are 0 numbers leftover in nums.

Example 3:

1
2
3
Input: nums = [0]
Output: [0,1]
Explanation: No pairs can be formed, and there is 1 number leftover in nums.

Constraints:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 100

Easy,计算每个数出现次数是奇数还是偶数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public:
vector<int> numberOfPairs(vector<int>& nums) {
vector<int> countNums(101, 0);
int odd = 0, even = 0;
for (int num: nums) {
countNums[num]++;
if (countNums[num] % 2 == 1) {
odd++;
} else {
even++;
odd--;
}
}
return {even, odd};
}
};

2342. Max Sum of a Pair With Equal Sum of Digits

You are given a 0-indexed array nums consisting of positive integers. You can choose two indices i and j, such that i != j, and the sum of digits of the number nums[i] is equal to that of nums[j].

Return the maximum value of nums[i] + nums[j] that you can obtain over all possible indices i and j that satisfy the conditions.

Example 1:

1
2
3
4
5
6
Input: nums = [18,43,36,13,7]
Output: 54
Explanation: The pairs (i, j) that satisfy the conditions are:
- (0, 2), both numbers have a sum of digits equal to 9, and their sum is 18 + 36 = 54.
- (1, 4), both numbers have a sum of digits equal to 7, and their sum is 43 + 7 = 50.
So the maximum sum that we can obtain is 54.

Example 2:

1
2
3
Input: nums = [10,12,19,14]
Output: -1
Explanation: There are no two numbers that satisfy the conditions, so we return -1.

Constraints:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 109

Medium,计算位数相同的数,保留最大的两个

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
class Solution {
public:
int maximumSum(vector<int>& nums) {
int res = -1;
vector<vector<int>> digitSumWithMAxTwo (82, vector<int> (3, 0));
for (int num: nums) {
int digitSum = countDigitSum(num);
digitSumWithMAxTwo[digitSum][0]++;
if (digitSumWithMAxTwo[digitSum][1] == 0) {
digitSumWithMAxTwo[digitSum][1] = num;
} else if (digitSumWithMAxTwo[digitSum][2] == 0) {
digitSumWithMAxTwo[digitSum][2] = num;
} else if (num > digitSumWithMAxTwo[digitSum][1]) {
digitSumWithMAxTwo[digitSum][2] = digitSumWithMAxTwo[digitSum][1];
digitSumWithMAxTwo[digitSum][1] = num;
} else if (num > digitSumWithMAxTwo[digitSum][2]) {
digitSumWithMAxTwo[digitSum][2] = num;
}
// cout<<digitSum<<","<<digitSumWithMAxTwo[digitSum][0]<<","<<digitSumWithMAxTwo[digitSum][1]<<","<<digitSumWithMAxTwo[digitSum][2]<<endl;
if (digitSumWithMAxTwo[digitSum][0] > 1) {
if (digitSumWithMAxTwo[digitSum][1] < digitSumWithMAxTwo[digitSum][2]) {
int temp = digitSumWithMAxTwo[digitSum][1];
digitSumWithMAxTwo[digitSum][1] = digitSumWithMAxTwo[digitSum][2];
digitSumWithMAxTwo[digitSum][2] = temp;
}
res = max(res, digitSumWithMAxTwo[digitSum][1] + digitSumWithMAxTwo[digitSum][2]);
}
}
return res;
}
int countDigitSum(int num) {
int res = 0;
while (num != 0) {
res += num % 10;
num = num / 10;
}
return res;
}
};

2343. Query Kth Smallest Trimmed Number

You are given a 0-indexed array of strings nums, where each string is of equal length and consists of only digits.

You are also given a 0-indexed 2D integer array queries where queries[i] = [ki, trimi]. For each queries[i], you need to:

  • Trim each number in nums to its rightmost trimi digits.
  • Determine the index of the kith smallest trimmed number in nums. If two trimmed numbers are equal, the number with the lower index is considered to be smaller.
  • Reset each number in nums to its original length.

Return an array answer of the same length as queries, where answer[i] is the answer to the ith query.

Note:

  • To trim to the rightmost x digits means to keep removing the leftmost digit, until only x digits remain.
  • Strings in nums may contain leading zeros.

Example 1:

1
2
3
4
5
6
7
8
Input: nums = ["102","473","251","814"], queries = [[1,1],[2,3],[4,2],[1,2]]
Output: [2,2,1,0]
Explanation:
1. After trimming to the last digit, nums = ["2","3","1","4"]. The smallest number is 1 at index 2.
2. Trimmed to the last 3 digits, nums is unchanged. The 2nd smallest number is 251 at index 2.
3. Trimmed to the last 2 digits, nums = ["02","73","51","14"]. The 4th smallest number is 73.
4. Trimmed to the last 2 digits, the smallest number is 2 at index 0.
Note that the trimmed number "02" is evaluated as 2.

Example 2:

1
2
3
4
5
6
Input: nums = ["24","37","96","04"], queries = [[2,1],[2,2]]
Output: [3,0]
Explanation:
1. Trimmed to the last digit, nums = ["4","7","6","4"]. The 2nd smallest number is 4 at index 3.
There are two occurrences of 4, but the one at index 0 is considered smaller than the one at index 3.
2. Trimmed to the last 2 digits, nums is unchanged. The 2nd smallest number is 24.

Constraints:

  • 1 <= nums.length <= 100
  • 1 <= nums[i].length <= 100
  • nums[i] consists of only digits.
  • All nums[i].length are equal.
  • 1 <= queries.length <= 100
  • queries[i].length == 2
  • 1 <= ki <= nums.length
  • 1 <= trimi <= nums[i].length

Medium,保存后几位数的大小排序并保存原索引

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
class Solution {
public:
vector<int> smallestTrimmedNumbers(vector<string>& nums, vector<vector<int>>& queries) {
vector<bool> isSearched(100, false);
vector<vector<pair<string, int>>> smallestTrimmedInorder(100);
vector<int> res;
for (auto &query: queries) {
if (isSearched[query[1] - 1]) {
res.push_back(smallestTrimmedInorder[query[1] - 1][query[0] - 1].second);
} else {
isSearched[query[1] - 1] = true;
vector<pair<string, int>> arr;
for (int j = 0; j < nums.size(); j++) {
string sub = nums[j].substr(nums[j].size() - query[1]);
arr.push_back(make_pair(sub, j));
}
sort(arr.begin(), arr.end());
smallestTrimmedInorder[query[1] - 1] = arr;
res.push_back(smallestTrimmedInorder[query[1] - 1][query[0] - 1].second);
}

}
return res;
}
};

2344. Minimum Deletions to Make Array Divisible

You are given two positive integer arrays nums and numsDivide. You can delete any number of elements from nums.

Return the minimum number of deletions such that the smallest element in nums *divides all the elements of* numsDivide. If this is not possible, return -1.

Note that an integer x divides y if y % x == 0.

Example 1:

1
2
3
4
5
6
7
Input: nums = [2,3,2,4,3], numsDivide = [9,6,9,3,15]
Output: 2
Explanation:
The smallest element in [2,3,2,4,3] is 2, which does not divide all the elements of numsDivide.
We use 2 deletions to delete the elements in nums that are equal to 2 which makes nums = [3,4,3].
The smallest element in [3,4,3] is 3, which divides all the elements of numsDivide.
It can be shown that 2 is the minimum number of deletions needed.

Example 2:

1
2
3
4
5
Input: nums = [4,3,6], numsDivide = [8,2,6,10]
Output: -1
Explanation:
We want the smallest element in nums to divide all the elements of numsDivide.
There is no way to delete elements from nums to allow this.

Constraints:

  • 1 <= nums.length, numsDivide.length <= 105
  • 1 <= nums[i], numsDivide[i] <= 109

Hard,求最大公约数

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:
int minOperations(vector<int>& nums, vector<int>& numsDivide) {
int gcdNum = gcd(numsDivide);
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size(); i++) {
if (nums[i] > gcdNum) return -1;
if (gcdNum % nums[i] == 0) {
return i;
}
}
return -1;
}
int gcd(vector<int> nums) {
int res = nums[0];
for (int i = 1; i < nums.size(); i++) {
res = gcdTwoNum(res, nums[i]);
if (res == 1) return 1;
}
return res;
}
int gcdTwoNum(int num1, int num2) {
if (num1 > num2) {
return gcdTwoNum(num2, num1);
}
while (num1 != 1) {
int q = num2 % num1;
if (q == 0) {
return num1;
}
num2 = num1;
num1 = q;
}
return num1;
}
};

Weekly Contest 303

image-20220724222811908

2351. First Letter to Appear Twice

Given a string s consisting of lowercase English letters, return the first letter to appear twice.

Note:

  • A letter a appears twice before another letter b if the second occurrence of a is before the second occurrence of b.
  • s will contain at least one letter that appears twice.

Example 1:

1
2
3
4
5
6
7
8
Input: s = "abccbaacz"
Output: "c"
Explanation:
The letter 'a' appears on the indexes 0, 5 and 6.
The letter 'b' appears on the indexes 1 and 4.
The letter 'c' appears on the indexes 2, 3 and 7.
The letter 'z' appears on the index 8.
The letter 'c' is the first letter to appear twice, because out of all the letters the index of its second occurrence is the smallest.

Example 2:

1
2
3
4
Input: s = "abcdd"
Output: "d"
Explanation:
The only letter that appears twice is 'd' so we return 'd'.

Constraints:

  • 2 <= s.length <= 100
  • s consists of lowercase English letters.
  • s has at least one repeated letter.

Easy,哈希

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public:
char repeatedCharacter(string s) {
vector<bool> isVisited(26, false);
for (char c: s) {
if (isVisited[c - 'a'] == true) {
return c;
}
isVisited[c - 'a'] = true;
}
return 'a';
}
};

2352. Equal Row and Column Pairs

Given a 0-indexed n x n integer matrix grid, return the number of pairs (Ri, Cj) such that row Ri and column Cj are equal.

A row and column pair is considered equal if they contain the same elements in the same order (i.e. an equal array).

Example 1:

img

1
2
3
4
Input: grid = [[3,2,1],[1,7,6],[2,7,7]]
Output: 1
Explanation: There is 1 equal row and column pair:
- (Row 2, Column 1): [2,7,7]

Example 2:

img

1
2
3
4
5
6
Input: grid = [[3,1,2,2],[1,4,4,5],[2,4,2,2],[2,4,2,2]]
Output: 3
Explanation: There are 3 equal row and column pairs:
- (Row 0, Column 0): [3,1,2,2]
- (Row 2, Column 2): [2,4,2,2]
- (Row 3, Column 2): [2,4,2,2]

Constraints:

  • n == grid.length == grid[i].length
  • 1 <= n <= 200
  • 1 <= grid[i][j] <= 105

Medium,拼接字符串+哈希

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 {
public:
int equalPairs(vector<vector<int>>& grid) {
int res = 0;
int n = grid.size();
unordered_map<string, int> dic;
for (int i = 0; i < n; i++) {
string row;
for (int j = 0; j < n; j++) {
row += to_string (grid[i][j]);
row += ',';
}
dic[row]++;
}

for (int i = 0; i < n; i++) {
string col;
for (int j = 0; j < n; j++) {
col += to_string (grid[j][i]);
col += ',';
}
if (dic.count(col)) res += dic[col];
}
return res;
}
};

Failed: 2353. Design a Food Rating System

Design a food rating system that can do the following:

  • Modify the rating of a food item listed in the system.
  • Return the highest-rated food item for a type of cuisine in the system.

Implement the FoodRatings class:

  • FoodRatings(String[] foods, String[] cuisines, int[] ratings)

    Initializes the system. The food items are described byfoods,cuisinesandratings, all of which have a length ofn.

    • foods[i] is the name of the ith food,
    • cuisines[i] is the type of cuisine of the ith food, and
    • ratings[i] is the initial rating of the ith food.
  • void changeRating(String food, int newRating) Changes the rating of the food item with the name food.

  • String highestRated(String cuisine) Returns the name of the food item that has the highest rating for the given type of cuisine. If there is a tie, return the item with the lexicographically smaller name.

Note that a string x is lexicographically smaller than string y if x comes before y in dictionary order, that is, either x is a prefix of y, or if i is the first position such that x[i] != y[i], then x[i] comes before y[i] in alphabetic order.

Example 1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Input
["FoodRatings", "highestRated", "highestRated", "changeRating", "highestRated", "changeRating", "highestRated"]
[[["kimchi", "miso", "sushi", "moussaka", "ramen", "bulgogi"], ["korean", "japanese", "japanese", "greek", "japanese", "korean"], [9, 12, 8, 15, 14, 7]], ["korean"], ["japanese"], ["sushi", 16], ["japanese"], ["ramen", 16], ["japanese"]]
Output
[null, "kimchi", "ramen", null, "sushi", null, "ramen"]

Explanation
FoodRatings foodRatings = new FoodRatings(["kimchi", "miso", "sushi", "moussaka", "ramen", "bulgogi"], ["korean", "japanese", "japanese", "greek", "japanese", "korean"], [9, 12, 8, 15, 14, 7]);
foodRatings.highestRated("korean"); // return "kimchi"
// "kimchi" is the highest rated korean food with a rating of 9.
foodRatings.highestRated("japanese"); // return "ramen"
// "ramen" is the highest rated japanese food with a rating of 14.
foodRatings.changeRating("sushi", 16); // "sushi" now has a rating of 16.
foodRatings.highestRated("japanese"); // return "sushi"
// "sushi" is the highest rated japanese food with a rating of 16.
foodRatings.changeRating("ramen", 16); // "ramen" now has a rating of 16.
foodRatings.highestRated("japanese"); // return "ramen"
// Both "sushi" and "ramen" have a rating of 16.
// However, "ramen" is lexicographically smaller than "sushi".

Constraints:

  • 1 <= n <= 2 * 104
  • n == foods.length == cuisines.length == ratings.length
  • 1 <= foods[i].length, cuisines[i].length <= 10
  • foods[i], cuisines[i] consist of lowercase English letters.
  • 1 <= ratings[i] <= 108
  • All the strings in foods are distinct.
  • food will be the name of a food item in the system across all calls to changeRating.
  • cuisine will be a type of cuisine of at least one food item in the system across all calls to highestRated.
  • At most 2 * 104 calls in total will be made to changeRating and highestRated.

Medium,STL接口不熟悉,哎

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 FoodRatings {
public:
struct Cmp {
bool operator () (const pair<int, string>&a, const pair<int, string>&b) const {
if (a.first == b.first)
return a.second < b.second;
return a.first > b.first;
}
};
unordered_map<string, pair<int, string>> foodDic;
unordered_map<string, set<pair<int, string>, Cmp>> cuisineDic;
FoodRatings(vector<string>& foods, vector<string>& cuisines, vector<int>& ratings) {
for (int i = 0; i < foods.size(); i++) {
foodDic[foods[i]]= make_pair(ratings[i], cuisines[i]);
cuisineDic[cuisines[i]].insert(make_pair(ratings[i], foods[i]));
}
}

void changeRating(string food, int newRating) {
string cuisine = foodDic[food].second;
int rate = foodDic[food].first;
cuisineDic[cuisine].erase(make_pair(rate, food));
cuisineDic[cuisine].insert(make_pair(newRating, food));
foodDic[food]= make_pair(newRating, cuisine);
}

string highestRated(string cuisine) {
return cuisineDic[cuisine].begin()->second;
}
};
/**
* Your FoodRatings object will be instantiated and called as such:
* FoodRatings* obj = new FoodRatings(foods, cuisines, ratings);
* obj->changeRating(food,newRating);
* string param_2 = obj->highestRated(cuisine);
*/

Failed: 2354. Number of Excellent Pairs

You are given a 0-indexed positive integer array nums and a positive integer k.

A pair of numbers (num1, num2) is called excellent if the following conditions are satisfied:

  • Both the numbers num1 and num2 exist in the array nums.
  • The sum of the number of set bits in num1 OR num2 and num1 AND num2 is greater than or equal to k, where OR is the bitwise OR operation and AND is the bitwise AND operation.

Return the number of distinct excellent pairs.

Two pairs (a, b) and (c, d) are considered distinct if either a != c or b != d. For example, (1, 2) and (2, 1) are distinct.

Note that a pair (num1, num2) such that num1 == num2 can also be excellent if you have at least one occurrence of num1 in the array.

Example 1:

1
2
3
4
5
6
7
Input: nums = [1,2,3,1], k = 3
Output: 5
Explanation: The excellent pairs are the following:
- (3, 3). (3 AND 3) and (3 OR 3) are both equal to (11) in binary. The total number of set bits is 2 + 2 = 4, which is greater than or equal to k = 3.
- (2, 3) and (3, 2). (2 AND 3) is equal to (10) in binary, and (2 OR 3) is equal to (11) in binary. The total number of set bits is 1 + 2 = 3.
- (1, 3) and (3, 1). (1 AND 3) is equal to (01) in binary, and (1 OR 3) is equal to (11) in binary. The total number of set bits is 1 + 2 = 3.
So the number of excellent pairs is 5.

Example 2:

1
2
3
Input: nums = [5,1,1], k = 10
Output: 0
Explanation: There are no excellent pairs for this array.

Constraints:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 109
  • 1 <= k <= 60

Hard,其实就是求每个数有多少1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public:
long long countExcellentPairs(vector<int>& nums, int k) {
long long res = 0;
unordered_map<int, int> bitCounts;
for (int num: unordered_set<int>(nums.begin(), nums.end())) {
bitCounts[__builtin_popcount(num)]++;
}
for (auto &[cx, ccx] : bitCounts) {
for (auto &[cy, ccy] : bitCounts) {
if (cx + cy >= k) {
res += ccx * ccy;
}
}
}
return res;
}
};

Weekly Contest 304

image-20220801091222647

2357. Make Array Zero by Subtracting Equal Amounts

You are given a non-negative integer array nums. In one operation, you must:

  • Choose a positive integer x such that x is less than or equal to the smallest non-zero element in nums.
  • Subtract x from every positive element in nums.

Return the minimum number of operations to make every element in nums equal to 0.

Example 1:

1
2
3
4
5
6
Input: nums = [1,5,0,3,5]
Output: 3
Explanation:
In the first operation, choose x = 1. Now, nums = [0,4,0,2,4].
In the second operation, choose x = 2. Now, nums = [0,2,0,0,2].
In the third operation, choose x = 2. Now, nums = [0,0,0,0,0].

Example 2:

1
2
3
Input: nums = [0]
Output: 0
Explanation: Each element in nums is already 0 so no operations are needed.

Constraints:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 100

Easy,保存每一轮之后的数据

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
class Solution {
public:
int minimumOperations(vector<int>& nums) {
set<int> pos;
for (int num: nums) {
if (num > 0) {
pos.insert(num);
}
}
int ans = 0;
while (pos.size() > 0) {
auto it = pos.begin();
int min_num = *it;
set<int> temp;
for (; it != pos.end(); it++) {
if (*it > min_num) {
temp.insert(*it - min_num);
}
}
pos = temp;
ans++;
}
return ans;
}
};

Failed: 2358. Maximum Number of Groups Entering a Competition

You are given a positive integer array grades which represents the grades of students in a university. You would like to enter all these students into a competition in ordered non-empty groups, such that the ordering meets the following conditions:

  • The sum of the grades of students in the ith group is less than the sum of the grades of students in the (i + 1)th group, for all groups (except the last).
  • The total number of students in the ith group is less than the total number of students in the (i + 1)th group, for all groups (except the last).

Return the maximum number of groups that can be formed.

Example 1:

1
2
3
4
5
6
7
Input: grades = [10,6,12,7,3,5]
Output: 3
Explanation: The following is a possible way to form 3 groups of students:
- 1st group has the students with grades = [12]. Sum of grades: 12. Student count: 1
- 2nd group has the students with grades = [6,7]. Sum of grades: 6 + 7 = 13. Student count: 2
- 3rd group has the students with grades = [10,3,5]. Sum of grades: 10 + 3 + 5 = 18. Student count: 3
It can be shown that it is not possible to form more than 3 groups.

Example 2:

1
2
3
Input: grades = [8,8]
Output: 1
Explanation: We can only form 1 group, since forming 2 groups would lead to an equal number of students in both groups.

Constraints:

  • 1 <= grades.length <= 105
  • 1 <= grades[i] <= 105

Medium,关键得找到数目也是增序这一条件。

1
2
3
4
5
6
7
8
9
10
11
class Solution {
public:
int maximumGroups(vector<int>& grades) {
int n = grades.size();
int total = 0, cur = 0;
while (total + cur + 1 <= n) {
total += ++cur;
}
return cur;
}
};

是用数学方法进行简化

1
2
3
4
5
6
class Solution {
public:
int maximumGroups(vector<int>& grades) {
return (int)(sqrt(grades.size() * 2 + 0.25) - 0.5);
}
};

2359. Find Closest Node to Given Two Nodes

You are given a directed graph of n nodes numbered from 0 to n - 1, where each node has at most one outgoing edge.

The graph is represented with a given 0-indexed array edges of size n, indicating that there is a directed edge from node i to node edges[i]. If there is no outgoing edge from i, then edges[i] == -1.

You are also given two integers node1 and node2.

Return the index of the node that can be reached from both node1 and node2, such that the maximum between the distance from node1 to that node, and from node2 to that node is minimized. If there are multiple answers, return the node with the smallest index, and if no possible answer exists, return -1.

Note that edges may contain cycles.

Example 1:

img

1
2
3
4
Input: edges = [2,2,3,-1], node1 = 0, node2 = 1
Output: 2
Explanation: The distance from node 0 to node 2 is 1, and the distance from node 1 to node 2 is 1.
The maximum of those two distances is 1. It can be proven that we cannot get a node with a smaller maximum distance than 1, so we return node 2.

Example 2:

img

1
2
3
4
Input: edges = [1,2,-1], node1 = 0, node2 = 2
Output: 2
Explanation: The distance from node 0 to node 2 is 2, and the distance from node 2 to itself is 0.
The maximum of those two distances is 2. It can be proven that we cannot get a node with a smaller maximum distance than 2, so we return node 2.

Constraints:

  • n == edges.length
  • 2 <= n <= 105
  • -1 <= edges[i] < n
  • edges[i] != i
  • 0 <= node1, node2 < n

Medium,使用哈希记录BFS路径,注意路径长度相同的情况

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:
int closestMeetingNode(vector<int>& edges, int node1, int node2) {
if (node1 == node2) return node1;
int cur1 = node1, cur2 = node2;
set<int> visited1, visited2;
visited1.insert(cur1);
visited2.insert(cur2);
bool isCircle1 = false, isCircle2 = false;
while ((isCircle1 == false && cur1 != -1) || (isCircle2 == false && cur2 != -1)) {
int min1 = -1, min2 = -1;
if (isCircle1 == false && cur1 != -1) {
cur1 = edges[cur1];
if (visited2.count(cur1)) min1 = cur1;
if (visited1.count(cur1)) {
isCircle1 = true;
} else {
visited1.insert(cur1);
}
}
if (isCircle2 == false && cur2 != -1) {
cur2 = edges[cur2];
if (visited1.count(cur2)) min2 = cur2;
if (visited2.count(cur2)) {
isCircle2 = true;
} else {
visited2.insert(cur2);
}
}
if (min1 > -1 || min2 > -1) {
if (min1 > -1 && min2 > -1) {
return min(min1, min2);
}
return min1 > -1 ? min1 : min2;
}

}
return -1;
}
};

2360. Longest Cycle in a Graph

You are given a directed graph of n nodes numbered from 0 to n - 1, where each node has at most one outgoing edge.

The graph is represented with a given 0-indexed array edges of size n, indicating that there is a directed edge from node i to node edges[i]. If there is no outgoing edge from node i, then edges[i] == -1.

Return the length of the longest cycle in the graph. If no cycle exists, return -1.

A cycle is a path that starts and ends at the same node.

Example 1:

img

1
2
3
4
Input: edges = [3,3,4,2,3]
Output: 3
Explanation: The longest cycle in the graph is the cycle: 2 -> 4 -> 3 -> 2.
The length of this cycle is 3, so 3 is returned.

Example 2:

img

1
2
3
Input: edges = [2,-1,3,1]
Output: -1
Explanation: There are no cycles in this graph.

Constraints:

  • n == edges.length
  • 2 <= n <= 105
  • -1 <= edges[i] < n
  • edges[i] != i

Hard,顺序遍历未访问且入度大于1的节点

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
41
42
43
44
45
46
47
class Solution {
public:
int longestCycle(vector<int>& edges) {
int n = edges.size();
vector<int> inDegree(n, 0);
for (int i = 0; i < n; i++) {
if (edges[i] != -1) {
inDegree[edges[i]]++;
}
}
vector<bool> isVisited(n, true);
int count = 0;
for (int i = 0; i < n; i++) {
if (inDegree[i] > 0) {
isVisited[i] = false;
count++;
}
}
int ans = -1;
int index = 0;
while (count > 0 && index < n) {
while (isVisited[index] == true && index < n) {
index++;
}
if (index == n) break;
int cur = index;
unordered_map<int, int> route;
int order = 0;
while (cur != -1) {
if (route.count(cur)) {
ans = max(ans, order - route[cur]);
break;
}
route[cur] = order;
order++;
if (isVisited[cur]) {
break;
} else {
isVisited[cur] = true;
count--;
}
cur = edges[cur];
}
}
return ans;
}
};

Weekly Contest 305

image-20220808075445305

2367. Number of Arithmetic Triplets

You are given a 0-indexed, strictly increasing integer array nums and a positive integer diff. A triplet (i, j, k) is an arithmetic triplet if the following conditions are met:

  • i < j < k,
  • nums[j] - nums[i] == diff, and
  • nums[k] - nums[j] == diff.

Return the number of unique arithmetic triplets.

Example 1:

1
2
3
4
5
Input: nums = [0,1,4,6,7,10], diff = 3
Output: 2
Explanation:
(1, 2, 4) is an arithmetic triplet because both 7 - 4 == 3 and 4 - 1 == 3.
(2, 4, 5) is an arithmetic triplet because both 10 - 7 == 3 and 7 - 4 == 3.

Example 2:

1
2
3
4
5
Input: nums = [4,5,6,7,8,9], diff = 2
Output: 2
Explanation:
(0, 2, 4) is an arithmetic triplet because both 8 - 6 == 2 and 6 - 4 == 2.
(1, 3, 5) is an arithmetic triplet because both 9 - 7 == 2 and 7 - 5 == 2.

Constraints:

  • 3 <= nums.length <= 200
  • 0 <= nums[i] <= 200
  • 1 <= diff <= 50
  • nums is strictly increasing.

Easy,哈希

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public:
int arithmeticTriplets(vector<int>& nums, int diff) {
unordered_set<int> dic;
for (int num: nums) {
dic.insert(num);
}
int res = 0;
for (int i = 0; i < nums.size() - 1; i++) {
if (dic.count(nums[i] + diff) && dic.count(nums[i] + 2 * diff)) {
res++;
}
}
return res;
}
};

2368. Reachable Nodes With Restrictions

There is an undirected tree with n nodes labeled from 0 to n - 1 and n - 1 edges.

You are given a 2D integer array edges of length n - 1 where edges[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the tree. You are also given an integer array restricted which represents restricted nodes.

Return the maximum number of nodes you can reach from node 0 without visiting a restricted node.

Note that node 0 will not be a restricted node.

Example 1:

img

1
2
3
4
Input: n = 7, edges = [[0,1],[1,2],[3,1],[4,0],[0,5],[5,6]], restricted = [4,5]
Output: 4
Explanation: The diagram above shows the tree.
We have that [0,1,2,3] are the only nodes that can be reached from node 0 without visiting a restricted node.

Example 2:

img

1
2
3
4
Input: n = 7, edges = [[0,1],[0,2],[0,5],[0,4],[3,2],[6,5]], restricted = [4,2,1]
Output: 3
Explanation: The diagram above shows the tree.
We have that [0,5,6] are the only nodes that can be reached from node 0 without visiting a restricted node.

Constraints:

  • 2 <= n <= 105
  • edges.length == n - 1
  • edges[i].length == 2
  • 0 <= ai, bi < n
  • ai != bi
  • edges represents a valid tree.
  • 1 <= restricted.length < n
  • 1 <= restricted[i] < n
  • All the values of restricted are unique.

Medium,BFS

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
class Solution {
public:
int reachableNodes(int n, vector<vector<int>>& edges, vector<int>& restricted) {
unordered_map<int, vector<int>> dic;
for (vector<int> &edge: edges) {
dic[edge[0]].push_back(edge[1]);
dic[edge[1]].push_back(edge[0]);
}
unordered_set<int> restricted_set;
for (int r: restricted) {
restricted_set.insert(r);
}
int res = 1;
unordered_set<int> visited;
queue<int> q;
visited.insert(0);
q.push(0);
while (!q.empty()) {
int cur = q.front();
q.pop();
for (int node: dic[cur]) {
if (!restricted_set.count(node) && !visited.count(node)) {
visited.insert(node);
q.push(node);
res++;
}
}
}
return res;
}
};

Failed: 2369. Check if There is a Valid Partition For The Array

You are given a 0-indexed integer array nums. You have to partition the array into one or more contiguous subarrays.

We call a partition of the array valid if each of the obtained subarrays satisfies one of the following conditions:

  1. The subarray consists of exactly 2 equal elements. For example, the subarray [2,2] is good.
  2. The subarray consists of exactly 3 equal elements. For example, the subarray [4,4,4] is good.
  3. The subarray consists of exactly 3 consecutive increasing elements, that is, the difference between adjacent elements is 1. For example, the subarray [3,4,5] is good, but the subarray [1,3,5] is not.

Return true if the array has at least one valid partition. Otherwise, return false.

Example 1:

1
2
3
4
Input: nums = [4,4,4,5,6]
Output: true
Explanation: The array can be partitioned into the subarrays [4,4] and [4,5,6].
This partition is valid, so we return true.

Example 2:

1
2
3
Input: nums = [1,1,1,2]
Output: false
Explanation: There is no valid partition for this array.

Constraints:

  • 2 <= nums.length <= 105
  • 1 <= nums[i] <= 106

Medium,动态规划就好,别用状态机,太复杂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public:
bool validPartition(vector<int>& nums) {
int n = nums.size();
vector<bool> dp(n + 1, false);
dp[0] = true;
for (int i = 1; i < n; i++) {
if (dp[i - 1] && nums[i] == nums[i - 1]
||
i > 1 && dp[i - 2] && nums[i] == nums[i - 1] && nums[i - 1] == nums[i - 2]
||
i > 1 && dp[i - 2] && (nums[i] == nums[i - 1] + 1) && (nums[i - 1] == nums[i - 2] + 1)
)
dp[i + 1] = true;
}
return dp[n];
}
};

2370. Longest Ideal Subsequence

You are given a string s consisting of lowercase letters and an integer k. We call a string t ideal if the following conditions are satisfied:

  • t is a subsequence of the string s.
  • The absolute difference in the alphabet order of every two adjacent letters in t is less than or equal to k.

Return the length of the longest ideal string.

A subsequence is a string that can be derived from another string by deleting some or no characters without changing the order of the remaining characters.

Note that the alphabet order is not cyclic. For example, the absolute difference in the alphabet order of 'a' and 'z' is 25, not 1.

Example 1:

1
2
3
4
Input: s = "acfgbd", k = 2
Output: 4
Explanation: The longest ideal string is "acbd". The length of this string is 4, so 4 is returned.
Note that "acfgbd" is not ideal because 'c' and 'f' have a difference of 3 in alphabet order.

Example 2:

1
2
3
Input: s = "abcd", k = 3
Output: 4
Explanation: The longest ideal string is "abcd". The length of this string is 4, so 4 is returned.

Constraints:

  • 1 <= s.length <= 105
  • 0 <= k <= 25
  • s consists of lowercase English letters.

Medium,动态规划+map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public:
int longestIdealString(string s, int k) {
int n = s.size();
vector<int> dp(n, 1);
vector<int> last(26, -1);
int res = 1;
for (int i = 0; i < n; i++) {
int num = s[i] - 'a';
int min_num = max(0, num - k);
int max_num = min(25, num + k);
for (int j = min_num; j <= max_num; j++) {
if (last[j] != -1) {
dp[i] = max(dp[i], dp[last[j]] + 1);
}
}
last[num] = i;
res = max(res, dp[i]);
}
return res;
}
};

Weekly Contest 306

image-20220821221725371

2373. Largest Local Values in a Matrix

You are given an n x n integer matrix grid.

Generate an integer matrix maxLocal of size (n - 2) x (n - 2) such that:

  • maxLocal[i][j] is equal to the largest value of the 3 x 3 matrix in grid centered around row i + 1 and column j + 1.

In other words, we want to find the largest value in every contiguous 3 x 3 matrix in grid.

Return the generated matrix.

Example 1:

img

1
2
3
4
Input: grid = [[9,9,8,1],[5,6,2,6],[8,2,6,4],[6,2,2,2]]
Output: [[9,9],[8,6]]
Explanation: The diagram above shows the original matrix and the generated matrix.
Notice that each value in the generated matrix corresponds to the largest value of a contiguous 3 x 3 matrix in grid.

Example 2:

img

1
2
3
Input: grid = [[1,1,1,1,1],[1,1,1,1,1],[1,1,2,1,1],[1,1,1,1,1],[1,1,1,1,1]]
Output: [[2,2,2],[2,2,2],[2,2,2]]
Explanation: Notice that the 2 is contained within every contiguous 3 x 3 matrix in grid.

Constraints:

  • n == grid.length == grid[i].length
  • 3 <= n <= 100
  • 1 <= grid[i][j] <= 100

Easy,暴力

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public:
vector<vector<int>> largestLocal(vector<vector<int>>& grid) {
int n = grid.size();
int n_dot = n - 2;
vector<vector<int>> res (n_dot, vector<int>(n_dot, 0));
for (int i = 0; i < n_dot; i++) {
for (int j = 0; j < n_dot; j++) {
for (int l = 0; l <= 2; l++) {
for (int m = 0; m <= 2; m++) {
res[i][j] = max(res[i][j], grid[i + l][j + m]);
}
}
}
}
return res;
}
};

2374. Node With Highest Edge Score

You are given a directed graph with n nodes labeled from 0 to n - 1, where each node has exactly one outgoing edge.

The graph is represented by a given 0-indexed integer array edges of length n, where edges[i] indicates that there is a directed edge from node i to node edges[i].

The edge score of a node i is defined as the sum of the labels of all the nodes that have an edge pointing to i.

Return the node with the highest edge score. If multiple nodes have the same edge score, return the node with the smallest index.

Example 1:

img

1
2
3
4
5
6
7
8
Input: edges = [1,0,0,0,0,7,7,5]
Output: 7
Explanation:
- The nodes 1, 2, 3 and 4 have an edge pointing to node 0. The edge score of node 0 is 1 + 2 + 3 + 4 = 10.
- The node 0 has an edge pointing to node 1. The edge score of node 1 is 0.
- The node 7 has an edge pointing to node 5. The edge score of node 5 is 7.
- The nodes 5 and 6 have an edge pointing to node 7. The edge score of node 7 is 5 + 6 = 11.
Node 7 has the highest edge score so return 7.

Example 2:

img

1
2
3
4
5
6
Input: edges = [2,0,0,2]
Output: 0
Explanation:
- The nodes 1 and 2 have an edge pointing to node 0. The edge score of node 0 is 1 + 2 = 3.
- The nodes 0 and 3 have an edge pointing to node 2. The edge score of node 2 is 0 + 3 = 3.
Nodes 0 and 2 both have an edge score of 3. Since node 0 has a smaller index, we return 0.

Constraints:

  • n == edges.length
  • 2 <= n <= 105
  • 0 <= edges[i] < n
  • edges[i] != i

Medium,统计每条边的入度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public:
int edgeScore(vector<int>& edges) {
int n = edges.size();
vector<long long> inDegree(n, 0);
for (int i = 0; i < n; i++) {
inDegree[edges[i]] += i;
}
int maxCount = 0;
for (int i = 1; i < n; i++) {
if (inDegree[i] > inDegree[maxCount]) {
maxCount = i;
}
}
return maxCount;
}
};

Failed: 2375. Construct Smallest Number From DI String

You are given a 0-indexed string pattern of length n consisting of the characters 'I' meaning increasing and 'D' meaning decreasing.

A 0-indexed string num of length n + 1 is created using the following conditions:

  • num consists of the digits '1' to '9', where each digit is used at most once.
  • If pattern[i] == 'I', then num[i] < num[i + 1].
  • If pattern[i] == 'D', then num[i] > num[i + 1].

Return the lexicographically smallest possible string num that meets the conditions.

Example 1:

1
2
3
4
5
6
7
8
Input: pattern = "IIIDIDDD"
Output: "123549876"
Explanation:
At indices 0, 1, 2, and 4 we must have that num[i] < num[i+1].
At indices 3, 5, 6, and 7 we must have that num[i] > num[i+1].
Some possible values of num are "245639871", "135749862", and "123849765".
It can be proven that "123549876" is the smallest possible num that meets the conditions.
Note that "123414321" is not possible because the digit '1' is used more than once.

Example 2:

1
2
3
4
5
Input: pattern = "DDD"
Output: "4321"
Explanation:
Some possible values of num are "9876", "7321", and "8742".
It can be proven that "4321" is the smallest possible num that meets the conditions.

Constraints:

  • 1 <= pattern.length <= 8
  • pattern consists of only the letters 'I' and 'D'.

Medium,使用栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public:
string smallestNumber(string pattern) {
string res, stk;
for (int i = 0; i <= pattern.length(); i++) {
stk.push_back('1' + i);
if (i == pattern.length() || pattern[i] == 'I') {
while (!stk.empty()) {
res.push_back(stk.back());
stk.pop_back();
}
}
}
return res;
}
};

Failed: 2376. Count Special Integers

We call a positive integer special if all of its digits are distinct.

Given a positive integer n, return the number of special integers that belong to the interval [1, n].

Example 1:

1
2
3
Input: n = 20
Output: 19
Explanation: All the integers from 1 to 20, except 11, are special. Thus, there are 19 special integers.

Example 2:

1
2
3
Input: n = 5
Output: 5
Explanation: All the integers from 1 to 5 are special.

Example 3:

1
2
3
4
Input: n = 135
Output: 110
Explanation: There are 110 integers from 1 to 135 that are special.
Some of the integers that are not special are: 22, 114, and 131.

Constraints:

  • 1 <= n <= 2 * 109

Hard,统计每位对应的数的个数

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
class Solution {
public:
int fact(int n){
if (n == 1 || n == 0) return 1;
return n * fact(n - 1);
}
int A(int m, int n){
return fact(m) / fact(m - n);
}

int countSpecialNumbers(int n) {
string strN = to_string(n);
int sz = strN.size();

int used[10] = {0};
int total = 0;

for (int i = 1; i < sz; i++)
total += 9 * A(9, i - 1);

for(int i = 0; i < sz; i++){
int num = strN[i] - 48;
for (int j = (i == 0 ? 1 : 0); j < num; j++){
if (used[j] != 0)
continue;
total += A(10 - 1 - i, sz - i - 1);
}
if(++used[num] > 1)
break;
if (i == sz - 1)
total += 1;
}
return total;
}
};

Weekly Contest 307

image-20220821223553499

2383. Minimum Hours of Training to Win a Competition

You are entering a competition, and are given two positive integers initialEnergy and initialExperience denoting your initial energy and initial experience respectively.

You are also given two 0-indexed integer arrays energy and experience, both of length n.

You will face n opponents in order. The energy and experience of the ith opponent is denoted by energy[i] and experience[i] respectively. When you face an opponent, you need to have both strictly greater experience and energy to defeat them and move to the next opponent if available.

Defeating the ith opponent increases your experience by experience[i], but decreases your energy by energy[i].

Before starting the competition, you can train for some number of hours. After each hour of training, you can either choose to increase your initial experience by one, or increase your initial energy by one.

Return the minimum number of training hours required to defeat all n opponents.

Example 1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Input: initialEnergy = 5, initialExperience = 3, energy = [1,4,3,2], experience = [2,6,3,1]
Output: 8
Explanation: You can increase your energy to 11 after 6 hours of training, and your experience to 5 after 2 hours of training.
You face the opponents in the following order:
- You have more energy and experience than the 0th opponent so you win.
Your energy becomes 11 - 1 = 10, and your experience becomes 5 + 2 = 7.
- You have more energy and experience than the 1st opponent so you win.
Your energy becomes 10 - 4 = 6, and your experience becomes 7 + 6 = 13.
- You have more energy and experience than the 2nd opponent so you win.
Your energy becomes 6 - 3 = 3, and your experience becomes 13 + 3 = 16.
- You have more energy and experience than the 3rd opponent so you win.
Your energy becomes 3 - 2 = 1, and your experience becomes 16 + 1 = 17.
You did a total of 6 + 2 = 8 hours of training before the competition, so we return 8.
It can be proven that no smaller answer exists.

Example 2:

1
2
3
Input: initialEnergy = 2, initialExperience = 4, energy = [1], experience = [3]
Output: 0
Explanation: You do not need any additional energy or experience to win the competition, so we return 0.

Constraints:

  • n == energy.length == experience.length
  • 1 <= n <= 100
  • 1 <= initialEnergy, initialExperience, energy[i], experience[i] <= 100

Easy,题目有点绕,按照2种方式计算最小值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public:
int minNumberOfHours(int initialEnergy, int initialExperience, vector<int>& energy, vector<int>& experience) {
int n = energy.size();
int initialEnergyNeeded = 1;
for (int i = 0; i < n; i++) {
initialEnergyNeeded += energy[i];
}
int res = initialEnergyNeeded > initialEnergy ? initialEnergyNeeded - initialEnergy : 0;
int neededExp = 0;
int exp = initialExperience;
for (int i = 0; i < n; i++) {
if (exp <= experience[i]) {
neededExp += experience[i] + 1 - exp;
exp = experience[i] + 1;
}
exp += experience[i];
}
return res + neededExp;
}
};

2384. Largest Palindromic Number

You are given a string num consisting of digits only.

Return the largest palindromic integer (in the form of a string) that can be formed using digits taken from num. It should not contain leading zeroes.

Notes:

  • You do not need to use all the digits of num, but you must use at least one digit.
  • The digits can be reordered.

Example 1:

1
2
3
4
5
Input: num = "444947137"
Output: "7449447"
Explanation:
Use the digits "4449477" from "444947137" to form the palindromic integer "7449447".
It can be shown that "7449447" is the largest palindromic integer that can be formed.

Example 2:

1
2
3
4
5
Input: num = "00009"
Output: "9"
Explanation:
It can be shown that "9" is the largest palindromic integer that can be formed.
Note that the integer returned should not contain leading zeroes.

Constraints:

  • 1 <= num.length <= 105
  • num consists of digits.

Medium,按从大到小排序,注意0和最大的奇数放中间

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
41
42
43
44
45
46
47
48
49
50
51
class Solution {
public:
string largestPalindromic(string num) {
vector<int> count(10, 0);
for (int i = 0; i < num.size(); i++) {
count[num[i] - '0']++;
}
string res = "";
int maxSingle = 10;
vector<int> cost(10, 0);
bool isNoZero = false;
for (int i = 9; i >= 1; i--) {
cost[i] = count[i] / 2;
if (cost[i] > 0) isNoZero = true;
count[i] -= 2 * cost[i];
if (count[i] == 1 && maxSingle == 10) {
maxSingle = i;
}
for (int j = 0; j < cost[i]; j++) {
res += ('0' + i);
}
}
if (isNoZero == true) {
cost[0] = count[0] / 2;
count[0] -= 2 * cost[0];
if (count[0] == 1 && maxSingle == 10) {
maxSingle = 0;
}
for (int j = 0; j < cost[0]; j++) {
res += '0';
}
}
if (maxSingle != 10) {
res += ('0' + maxSingle);
}
if (maxSingle == 10 && isNoZero == false) {
res += '0';
}
if (isNoZero == true) {
for (int j = 0; j < cost[0]; j++) {
res += '0';
}
}
for (int i = 1; i <= 9; i++) {
for (int j = 0; j < cost[i]; j++) {
res += ('0' + i);
}
}
return res;
}
};

2385. Amount of Time for Binary Tree to Be Infected

You are given the root of a binary tree with unique values, and an integer start. At minute 0, an infection starts from the node with value start.

Each minute, a node becomes infected if:

  • The node is currently uninfected.
  • The node is adjacent to an infected node.

Return the number of minutes needed for the entire tree to be infected.

Example 1:

img

1
2
3
4
5
6
7
8
9
Input: root = [1,5,3,null,4,10,6,9,2], start = 3
Output: 4
Explanation: The following nodes are infected during:
- Minute 0: Node 3
- Minute 1: Nodes 1, 10 and 6
- Minute 2: Node 5
- Minute 3: Node 4
- Minute 4: Nodes 9 and 2
It takes 4 minutes for the whole tree to be infected so we return 4.

Example 2:

img

1
2
3
Input: root = [1], start = 1
Output: 0
Explanation: At minute 0, the only node in the tree is infected so we return 0.

Constraints:

  • The number of nodes in the tree is in the range [1, 105].
  • 1 <= Node.val <= 105
  • Each node has a unique value.
  • A node with a value of start exists in the tree.

Medium,2次bfs

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int amountOfTime(TreeNode* root, int start) {
unordered_map<TreeNode*, TreeNode*> dic;
TreeNode *pRoot;
queue<TreeNode*> q;
q.push(root);
while (q.size()) {
int sz = q.size();
for (int i = 0; i < sz; i++) {
TreeNode* parent = q.front();
if (parent->val == start) pRoot = parent;
q.pop();
if (parent->left) {
dic[parent->left] = parent;
q.push(parent->left);
}
if (parent->right) {
dic[parent->right] = parent;
q.push(parent->right);
}
}
}
unordered_set<TreeNode*> visited;
int level = 0;
q.push(pRoot);
visited.insert(pRoot);
while (q.size()) {
int sz = q.size();
for (int i = 0; i < sz; i++) {
TreeNode* cur = q.front();
q.pop();
if (dic[cur] && !visited.count(dic[cur])) {
q.push(dic[cur]);
visited.insert(dic[cur]);
}
if (cur->left && !visited.count(cur->left)) {
q.push(cur->left);
visited.insert(cur->left);
}
if (cur->right && !visited.count(cur->right)) {
q.push(cur->right);
visited.insert(cur->right);
}
}
level++;
}
return level - 1;
}
};

Failed: 2386. Find the K-Sum of an Array

You are given an integer array nums and a positive integer k. You can choose any subsequence of the array and sum all of its elements together.

We define the K-Sum of the array as the kth largest subsequence sum that can be obtained (not necessarily distinct).

Return the K-Sum of the array.

A subsequence is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.

Note that the empty subsequence is considered to have a sum of 0.

Example 1:

1
2
3
4
5
Input: nums = [2,4,-2], k = 5
Output: 2
Explanation: All the possible subsequence sums that we can obtain are the following sorted in decreasing order:
- 6, 4, 4, 2, 2, 0, 0, -2.
The 5-Sum of the array is 2.

Example 2:

1
2
3
Input: nums = [1,-2,3,4,-10,12], k = 16
Output: 10
Explanation: The 16-Sum of the array is 10.

Constraints:

  • n == nums.length
  • 1 <= n <= 105
  • -109 <= nums[i] <= 109
  • 1 <= k <= min(2000, 2n)

Hard,优先队列

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
class Solution {
public:
long long kSum(vector<int>& nums, int k) {
int n = nums.size();
// sm 表示所有数的和,neg 表示所有负数之和
long long sm = 0, neg = 0;
for (int i = 0; i < n; i++) {
sm += nums[i];
if (nums[i] < 0) {
neg += nums[i];
nums[i] = -nums[i];
}
}
sort(nums.begin(), nums.end());

// k = 1 时的答案,也就是空集的和
long long ans = 0;
priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq;
pq.push(make_pair(nums[0], 0));
for (int i = 2; i <= k; i++) {
auto p = pq.top();
pq.pop();
// k = i 时的答案
ans = p.first;
if (p.second == n - 1) continue;
pq.push(make_pair(p.first + nums[p.second + 1], p.second + 1));
pq.push(make_pair(p.first - nums[p.second] + nums[p.second + 1], p.second + 1));
}
return sm - (neg + ans);
}
};

Weekly Contest 308

image-20220828220718410

2389. Longest Subsequence With Limited Sum

You are given an integer array nums of length n, and an integer array queries of length m.

Return an array answer of length m where answer[i] is the maximum size of a subsequence that you can take from nums such that the sum of its elements is less than or equal to queries[i].

A subsequence is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.

Example 1:

1
2
3
4
5
6
Input: nums = [4,5,2,1], queries = [3,10,21]
Output: [2,3,4]
Explanation: We answer the queries as follows:
- The subsequence [2,1] has a sum less than or equal to 3. It can be proven that 2 is the maximum size of such a subsequence, so answer[0] = 2.
- The subsequence [4,5,1] has a sum less than or equal to 10. It can be proven that 3 is the maximum size of such a subsequence, so answer[1] = 3.
- The subsequence [4,5,2,1] has a sum less than or equal to 21. It can be proven that 4 is the maximum size of such a subsequence, so answer[2] = 4.

Example 2:

1
2
3
Input: nums = [2,3,4,5], queries = [1]
Output: [0]
Explanation: The empty subsequence is the only subsequence that has a sum less than or equal to 1, so answer[0] = 0.

Constraints:

  • n == nums.length
  • m == queries.length
  • 1 <= n, m <= 1000
  • 1 <= nums[i], queries[i] <= 106

Easy,其实比较复杂,前缀和+二分查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public:
vector<int> answerQueries(vector<int>& nums, vector<int>& queries) {
sort(nums.begin(), nums.end());
int n = nums.size();
vector<int> prefix(n, 0);
prefix[0] = nums[0];
for (int i = 1; i < n; i++) {
prefix[i] = prefix[i - 1] + nums[i];
}
int m = queries.size();
vector<int> res(m, 0);
for (int i = 0; i < m; i++) {
res[i] = upper_bound(prefix.begin(), prefix.end(), queries[i]) - prefix.begin();
}
return res;
}
};

2390. Removing Stars From a String

You are given a string s, which contains stars *.

In one operation, you can:

  • Choose a star in s.
  • Remove the closest non-star character to its left, as well as remove the star itself.

Return the string after all stars have been removed.

Note:

  • The input will be generated such that the operation is always possible.
  • It can be shown that the resulting string will always be unique.

Example 1:

1
2
3
4
5
6
7
Input: s = "leet**cod*e"
Output: "lecoe"
Explanation: Performing the removals from left to right:
- The closest character to the 1st star is 't' in "leet**cod*e". s becomes "lee*cod*e".
- The closest character to the 2nd star is 'e' in "lee*cod*e". s becomes "lecod*e".
- The closest character to the 3rd star is 'd' in "lecod*e". s becomes "lecoe".
There are no more stars, so we return "lecoe".

Example 2:

1
2
3
Input: s = "erase*****"
Output: ""
Explanation: The entire string is removed, so we return an empty string.

Constraints:

  • 1 <= s.length <= 105
  • s consists of lowercase English letters and stars *.
  • The operation above can be performed on s.

Medium,栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public:
string removeStars(string s) {
string res;
for (char c: s) {
if (c != '*') {
res.push_back(c);
} else {
if (res.size() != 0) {
res.pop_back();
}
}
}
return res;
}
};

2391. Minimum Amount of Time to Collect Garbage

You are given a 0-indexed array of strings garbage where garbage[i] represents the assortment of garbage at the ith house. garbage[i] consists only of the characters 'M', 'P' and 'G' representing one unit of metal, paper and glass garbage respectively. Picking up one unit of any type of garbage takes 1 minute.

You are also given a 0-indexed integer array travel where travel[i] is the number of minutes needed to go from house i to house i + 1.

There are three garbage trucks in the city, each responsible for picking up one type of garbage. Each garbage truck starts at house 0 and must visit each house in order; however, they do not need to visit every house.

Only one garbage truck may be used at any given moment. While one truck is driving or picking up garbage, the other two trucks cannot do anything.

Return the minimum number of minutes needed to pick up all the garbage.

Example 1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Input: garbage = ["G","P","GP","GG"], travel = [2,4,3]
Output: 21
Explanation:
The paper garbage truck:
1. Travels from house 0 to house 1
2. Collects the paper garbage at house 1
3. Travels from house 1 to house 2
4. Collects the paper garbage at house 2
Altogether, it takes 8 minutes to pick up all the paper garbage.
The glass garbage truck:
1. Collects the glass garbage at house 0
2. Travels from house 0 to house 1
3. Travels from house 1 to house 2
4. Collects the glass garbage at house 2
5. Travels from house 2 to house 3
6. Collects the glass garbage at house 3
Altogether, it takes 13 minutes to pick up all the glass garbage.
Since there is no metal garbage, we do not need to consider the metal garbage truck.
Therefore, it takes a total of 8 + 13 = 21 minutes to collect all the garbage.

Example 2:

1
2
3
4
5
6
7
Input: garbage = ["MMM","PGM","GP"], travel = [3,10]
Output: 37
Explanation:
The metal garbage truck takes 7 minutes to pick up all the metal garbage.
The paper garbage truck takes 15 minutes to pick up all the paper garbage.
The glass garbage truck takes 15 minutes to pick up all the glass garbage.
It takes a total of 7 + 15 + 15 = 37 minutes to collect all the garbage.

Constraints:

  • 2 <= garbage.length <= 105
  • garbage[i] consists of only the letters 'M', 'P', and 'G'.
  • 1 <= garbage[i].length <= 10
  • travel.length == garbage.length - 1
  • 1 <= travel[i] <= 100

Medium,哈希

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
class Solution {
public:
int garbageCollection(vector<string>& garbage, vector<int>& travel) {
int n = garbage.size();
int mTravel = 0, pTravel = 0, gTravel = 0;
int mPick = 0, pPick = 0, gPick = 0;
int totalTravel = 0;
for (int i = 0; i < n; i++) {
for (char c: garbage[i]) {
if (c == 'M') {
mPick++;
mTravel = totalTravel;
} else if (c == 'P') {
pPick++;
pTravel = totalTravel;
} else if (c == 'G') {
gPick++;
gTravel = totalTravel;
}
}
if (i != n - 1) {
totalTravel += travel[i];
}
}
return mTravel + pTravel + gTravel + mPick + pPick + gPick;
}
};

Failed: 2392. Build a Matrix With Conditions

You are given a positive integer k. You are also given:

  • a 2D integer array rowConditions of size n where rowConditions[i] = [abovei, belowi], and
  • a 2D integer array colConditions of size m where colConditions[i] = [lefti, righti].

The two arrays contain integers from 1 to k.

You have to build a k x k matrix that contains each of the numbers from 1 to k exactly once. The remaining cells should have the value 0.

The matrix should also satisfy the following conditions:

  • The number abovei should appear in a row that is strictly above the row at which the number belowi appears for all i from 0 to n - 1.
  • The number lefti should appear in a column that is strictly left of the column at which the number righti appears for all i from 0 to m - 1.

Return *any matrix that satisfies the conditions*. If no answer exists, return an empty matrix.

Example 1:

img

1
2
3
4
5
6
7
8
9
10
Input: k = 3, rowConditions = [[1,2],[3,2]], colConditions = [[2,1],[3,2]]
Output: [[3,0,0],[0,0,1],[0,2,0]]
Explanation: The diagram above shows a valid example of a matrix that satisfies all the conditions.
The row conditions are the following:
- Number 1 is in row 1, and number 2 is in row 2, so 1 is above 2 in the matrix.
- Number 3 is in row 0, and number 2 is in row 2, so 3 is above 2 in the matrix.
The column conditions are the following:
- Number 2 is in column 1, and number 1 is in column 2, so 2 is left of 1 in the matrix.
- Number 3 is in column 0, and number 2 is in column 1, so 3 is left of 2 in the matrix.
Note that there may be multiple correct answers.

Example 2:

1
2
3
4
Input: k = 3, rowConditions = [[1,2],[2,3],[3,1],[2,3]], colConditions = [[2,1]]
Output: []
Explanation: From the first two conditions, 3 has to be below 1 but the third conditions needs 3 to be above 1 to be satisfied.
No matrix can satisfy all the conditions, so we return the empty matrix.

Constraints:

  • 2 <= k <= 400
  • 1 <= rowConditions.length, colConditions.length <= 104
  • rowConditions[i].length == colConditions[i].length == 2
  • 1 <= abovei, belowi, lefti, righti <= k
  • abovei != belowi
  • lefti != righti

Hard,拓扑排序

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
class Solution {
public:
vector<vector<int>> buildMatrix(int k, vector<vector<int>>& rowConditions, vector<vector<int>>& colConditions) {
vector<int> order1 = generate_topological_sort(rowConditions, k);
vector<int> order2 = generate_topological_sort(colConditions, k);
if (order1.size() < k || order2.size() < k) return {};
unordered_map<int, int> m;
for (int i = 0; i < k; i++) m[order2[i]] = i;
vector<vector<int>> ans(k, vector<int>(k, 0));
for (int i = 0; i < k; i++) {
ans[i][m[order1[i]]] = order1[i];
}
return ans;
}
vector<int> generate_topological_sort(vector<vector<int>> &A, int k) {
vector<int> deg(k, 0), order;
vector<vector<int>> graph(k, vector<int>(0));
queue<int> q;
for (auto &c: A) {
graph[c[0] - 1].push_back(c[1] - 1);
deg[c[1] - 1]++;
}
for(int i = 0; i < k; i++)
if (!deg[i]) q.push(i);
while (!q.empty()) {
int x = q.front(); q.pop();
order.push_back(x + 1);
for (int& y: graph[x])
if (--deg[y] == 0)
q.push(y);
}
return order;
}
};

Weekly Contest 309

image-20220904223659259

2399. Check Distances Between Same Letters

You are given a 0-indexed string s consisting of only lowercase English letters, where each letter in s appears exactly twice. You are also given a 0-indexed integer array distance of length 26.

Each letter in the alphabet is numbered from 0 to 25 (i.e. 'a' -> 0, 'b' -> 1, 'c' -> 2, … , 'z' -> 25).

In a well-spaced string, the number of letters between the two occurrences of the ith letter is distance[i]. If the ith letter does not appear in s, then distance[i] can be ignored.

Return true if s is a well-spaced string, otherwise return false.

Example 1:

1
2
3
4
5
6
7
8
Input: s = "abaccb", distance = [1,3,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
Output: true
Explanation:
- 'a' appears at indices 0 and 2 so it satisfies distance[0] = 1.
- 'b' appears at indices 1 and 5 so it satisfies distance[1] = 3.
- 'c' appears at indices 3 and 4 so it satisfies distance[2] = 0.
Note that distance[3] = 5, but since 'd' does not appear in s, it can be ignored.
Return true because s is a well-spaced string.

Example 2:

1
2
3
4
5
Input: s = "aa", distance = [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
Output: false
Explanation:
- 'a' appears at indices 0 and 1 so there are zero letters between them.
Because distance[0] = 1, s is not a well-spaced string.

Constraints:

  • 2 <= s.length <= 52
  • s consists only of lowercase English letters.
  • Each letter appears in s exactly twice.
  • distance.length == 26
  • 0 <= distance[i] <= 50

Easy,保存每个字母出现的位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public:
bool checkDistances(string s, vector<int>& distance) {
vector<int> pre(26, -1);
for (int i = 0; i < s.size(); i++) {
int num = s[i] - 'a';
if (pre[num] == -1) {
pre[num] = i;
} else {
if (i - pre[num] - 1 != distance[num]) return false;
}
}
return true;
}
};

Failed: 2400. Number of Ways to Reach a Position After Exactly k Steps

You are given two positive integers startPos and endPos. Initially, you are standing at position startPos on an infinite number line. With one step, you can move either one position to the left, or one position to the right.

Given a positive integer k, return the number of different ways to reach the position endPos starting from startPos, such that you perform exactly k steps. Since the answer may be very large, return it modulo 109 + 7.

Two ways are considered different if the order of the steps made is not exactly the same.

Note that the number line includes negative integers.

Example 1:

1
2
3
4
5
6
7
Input: startPos = 1, endPos = 2, k = 3
Output: 3
Explanation: We can reach position 2 from 1 in exactly 3 steps in three ways:
- 1 -> 2 -> 3 -> 2.
- 1 -> 2 -> 1 -> 2.
- 1 -> 0 -> 1 -> 2.
It can be proven that no other way is possible, so we return 3.

Example 2:

1
2
3
Input: startPos = 2, endPos = 5, k = 10
Output: 0
Explanation: It is impossible to reach position 5 from position 2 in exactly 10 steps.

Constraints:

  • 1 <= startPos, endPos, k <= 1000

Medium,求组合数使用乘除法有点坑,实在做不出来建议动态规划

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public:
int mod = 1e9 + 7;
int numberOfWays(int startPos, int endPos, int k) {
if ((k - (endPos - startPos)) % 2 != 0 || abs(k) < abs(endPos - startPos)) return 0;
int pos = (endPos - startPos + k) / 2;
int neg = k - pos;
long long int res = 1;
int a = pos > neg ? neg : pos;
for (int i = 0; i < a; i++) {
res = res * (k - i) % mod;
res = res * inv(i + 1) % mod;
}
return res;
}
long inv(long a) {
if (a == 1) return 1;
return (mod - mod / a) * inv(mod % a) % mod;
}
};

Failed: 2401. Longest Nice Subarray

You are given an array nums consisting of positive integers.

We call a subarray of nums nice if the bitwise AND of every pair of elements that are in different positions in the subarray is equal to 0.

Return the length of the longest nice subarray.

A subarray is a contiguous part of an array.

Note that subarrays of length 1 are always considered nice.

Example 1:

1
2
3
4
5
6
7
Input: nums = [1,3,8,48,10]
Output: 3
Explanation: The longest nice subarray is [3,8,48]. This subarray satisfies the conditions:
- 3 AND 8 = 0.
- 3 AND 48 = 0.
- 8 AND 48 = 0.
It can be proven that no longer nice subarray can be obtained, so we return 3.

Example 2:

1
2
3
Input: nums = [3,1,5,11,13]
Output: 1
Explanation: The length of the longest nice subarray is 1. Any subarray of length 1 can be chosen.

Constraints:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 109

Medium,滑动窗口+位运算,挨个统计位会超时

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public:
int longestNiceSubarray(vector<int>& nums) {
int AND = 0, i = 0, res = 0, n = nums.size();
for (int j = 0; j < n; j++) {
while ((AND & nums[j]) > 0)
AND ^= nums[i++];
AND |= nums[j];
res = max(res, j - i + 1);
}
return res;
}
};

2402. Meeting Rooms III

You are given an integer n. There are n rooms numbered from 0 to n - 1.

You are given a 2D integer array meetings where meetings[i] = [starti, endi] means that a meeting will be held during the half-closed time interval [starti, endi). All the values of starti are unique.

Meetings are allocated to rooms in the following manner:

  1. Each meeting will take place in the unused room with the lowest number.
  2. If there are no available rooms, the meeting will be delayed until a room becomes free. The delayed meeting should have the same duration as the original meeting.
  3. When a room becomes unused, meetings that have an earlier original start time should be given the room.

Return the number of the room that held the most meetings. If there are multiple rooms, return the room with the lowest number.

A half-closed interval [a, b) is the interval between a and b including a and not including b.

Example 1:

1
2
3
4
5
6
7
8
9
10
Input: n = 2, meetings = [[0,10],[1,5],[2,7],[3,4]]
Output: 0
Explanation:
- At time 0, both rooms are not being used. The first meeting starts in room 0.
- At time 1, only room 1 is not being used. The second meeting starts in room 1.
- At time 2, both rooms are being used. The third meeting is delayed.
- At time 3, both rooms are being used. The fourth meeting is delayed.
- At time 5, the meeting in room 1 finishes. The third meeting starts in room 1 for the time period [5,10).
- At time 10, the meetings in both rooms finish. The fourth meeting starts in room 0 for the time period [10,11).
Both rooms 0 and 1 held 2 meetings, so we return 0.

Example 2:

1
2
3
4
5
6
7
8
9
10
11
Input: n = 3, meetings = [[1,20],[2,10],[3,5],[4,9],[6,8]]
Output: 1
Explanation:
- At time 1, all three rooms are not being used. The first meeting starts in room 0.
- At time 2, rooms 1 and 2 are not being used. The second meeting starts in room 1.
- At time 3, only room 2 is not being used. The third meeting starts in room 2.
- At time 4, all three rooms are being used. The fourth meeting is delayed.
- At time 5, the meeting in room 2 finishes. The fourth meeting starts in room 2 for the time period [5,10).
- At time 6, all three rooms are being used. The fifth meeting is delayed.
- At time 10, the meetings in rooms 1 and 2 finish. The fifth meeting starts in room 1 for the time period [10,12).
Room 0 held 1 meeting while rooms 1 and 2 each held 2 meetings, so we return 1.

Constraints:

  • 1 <= n <= 100
  • 1 <= meetings.length <= 105
  • meetings[i].length == 2
  • 0 <= starti < endi <= 5 * 105
  • All the values of starti are unique.

Hard,优先队列

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
bool compare(vector<int>& v1, vector<int>& v2) {
return v1[0] < v2[0];
}
class Solution {
public:
int mostBooked(int n, vector<vector<int>>& meetings) {
/* Sort the meetings based on start_time */
sort(meetings.begin(), meetings.end(), compare);

/* Create a priority queue for engaged rooms. Each node of PQ will store {current_meeting_ending_time, room_number} */
priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> engaged;

/* Create a priority queue for non-engaged rooms. Each node of PQ will store {room_number} */
priority_queue<int, vector<int>, greater<int>> unused;

/* Frequency map to store the frequency of meetings in each room */
unordered_map<int, int> freq;

/* Currently all the rooms are mepty */
for (int i = 0; i < n; i++) {
unused.push(i);
}

for (auto x:meetings) {
int s = x[0], e = x[1];

/* Move the meeting rooms in engaged, with ending_time <= s, to unused */
while(engaged.size() > 0 && engaged.top().first <= s) {
int room = engaged.top().second;
engaged.pop();

unused.push(room);
}

/* If there are multiple empty rooms, choose the one with lower room_number */
if (unused.size() > 0) {
int room = unused.top();
unused.pop();

freq[abs(room)]++;

/* Mark the room as engaged */
engaged.push({e, room});
}
/* If there are no empty rooms, wait for the engaged room with nearest ending time to empty */
else {
pair<long long, int> topmost = engaged.top();
engaged.pop();

freq[abs(topmost.second)] += 1;

/* Since duration has to be the same, the newEnd will be sum(end_time_of_the_prev_meeting, duration) */
long long newEnd = topmost.first;
newEnd += (e - s);

/* Mark the room as engaged */
engaged.push({newEnd, topmost.second});
}
}

/* Find the lowest room_number with maximum frequency */
int maxi = 0;
for (int i = 1; i < n; i++) {
if (freq[i] > freq[maxi])
maxi = i;
}
return maxi;
}
};

Weekly Contest 310

image-20220919090522788

2404. Most Frequent Even Element

Given an integer array nums, return the most frequent even element.

If there is a tie, return the smallest one. If there is no such element, return -1.

Example 1:

1
2
3
4
5
Input: nums = [0,1,2,2,4,4,1]
Output: 2
Explanation:
The even elements are 0, 2, and 4. Of these, 2 and 4 appear the most.
We return the smallest one, which is 2.

Example 2:

1
2
3
Input: nums = [4,4,4,9,2,4]
Output: 4
Explanation: 4 is the even element appears the most.

Example 3:

1
2
3
Input: nums = [29,47,21,41,13,37,25,7]
Output: -1
Explanation: There is no even element.

Constraints:

  • 1 <= nums.length <= 2000
  • 0 <= nums[i] <= 105

Easy,计数

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 {
public:
int mostFrequentEven(vector<int>& nums) {
unordered_map<int, int> count;
int maxCount = -1, minNum = -1;
for (int num: nums) {
if (num % 2 == 0) {
if (count[num]) {
count[num]++;
} else {
count[num] = 1;
}
if (count[num] > maxCount) {
maxCount = count[num];
minNum = num;
} else if (count[num] == maxCount && num < minNum) {
minNum = num;
}
}
}
return minNum;
}
};

2405. Optimal Partition of String

Given a string s, partition the string into one or more substrings such that the characters in each substring are unique. That is, no letter appears in a single substring more than once.

Return the minimum number of substrings in such a partition.

Note that each character should belong to exactly one substring in a partition.

Example 1:

1
2
3
4
5
Input: s = "abacaba"
Output: 4
Explanation:
Two possible partitions are ("a","ba","cab","a") and ("ab","a","ca","ba").
It can be shown that 4 is the minimum number of substrings needed.

Example 2:

1
2
3
4
Input: s = "ssssss"
Output: 6
Explanation:
The only valid partition is ("s","s","s","s","s","s").

Constraints:

  • 1 <= s.length <= 105
  • s consists of only English lowercase letters.

Medium,双指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public:
int partitionString(string s) {
int res = 1;
vector<bool> window(26, false);
window[s[0] - 'a'] = true;
for (int i = 1; i < s.size(); i++) {
if (window[s[i] - 'a'] == true) {
res++;
window.assign(26, false);
}
window[s[i] - 'a'] = true;
}
return res;
}
};

2406. Divide Intervals Into Minimum Number of Groups

You are given a 2D integer array intervals where intervals[i] = [lefti, righti] represents the inclusive interval [lefti, righti].

You have to divide the intervals into one or more groups such that each interval is in exactly one group, and no two intervals that are in the same group intersect each other.

Return the minimum number of groups you need to make.

Two intervals intersect if there is at least one common number between them. For example, the intervals [1, 5] and [5, 8] intersect.

Example 1:

1
2
3
4
5
6
7
Input: intervals = [[5,10],[6,8],[1,5],[2,3],[1,10]]
Output: 3
Explanation: We can divide the intervals into the following groups:
- Group 1: [1, 5], [6, 8].
- Group 2: [2, 3], [5, 10].
- Group 3: [1, 10].
It can be proven that it is not possible to divide the intervals into fewer than 3 groups.

Example 2:

1
2
3
Input: intervals = [[1,3],[5,6],[8,10],[11,13]]
Output: 1
Explanation: None of the intervals overlap, so we can put all of them in one group.

Constraints:

  • 1 <= intervals.length <= 105
  • intervals[i].length == 2
  • 1 <= lefti <= righti <= 106

Medium,排序+贪心(利用优先队列)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public:
int minGroups(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end(), [](vector<int>& v1, vector<int>& v2){
if (v1[0] != v2[0]) return v1[0] < v2[0];
return v1[1] < v2[1];
});
priority_queue<int, vector<int>, greater<int>> pq;
pq.push(intervals[0][1]);
for (int i = 1; i < intervals.size(); i++) {
if (pq.top() < intervals[i][0]) {
pq.pop();
pq.push(intervals[i][1]);
} else {
pq.push(intervals[i][1]);
}
}
return pq.size();
}
};

看到大佬的解法,开始+1,结束-1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public:
int minGroups(vector<vector<int>>& intervals) {
vector<vector<int>> A;
for (auto& v : intervals) {
A.push_back({v[0], 1});
A.push_back({v[1] + 1, -1});
}
int res = 0, cur = 0;
sort(A.begin(), A.end());
for (auto& v : A)
res = max(res, cur += v[1]);
return res;
}
};

Failed: 2407. Longest Increasing Subsequence II

You are given an integer array nums and an integer k.

Find the longest subsequence of nums that meets the following requirements:

  • The subsequence is strictly increasing and
  • The difference between adjacent elements in the subsequence is at most k.

Return the length of the longest subsequence that meets the requirements.

A subsequence is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.

Example 1:

1
2
3
4
5
6
Input: nums = [4,2,1,4,3,4,5,8,15], k = 3
Output: 5
Explanation:
The longest subsequence that meets the requirements is [1,3,4,5,8].
The subsequence has a length of 5, so we return 5.
Note that the subsequence [1,3,4,5,8,15] does not meet the requirements because 15 - 8 = 7 is larger than 3.

Example 2:

1
2
3
4
5
Input: nums = [7,4,5,1,8,12,4,7], k = 5
Output: 4
Explanation:
The longest subsequence that meets the requirements is [4,5,8,12].
The subsequence has a length of 4, so we return 4.

Example 3:

1
2
3
4
5
Input: nums = [1,5], k = 1
Output: 1
Explanation:
The longest subsequence that meets the requirements is [1].
The subsequence has a length of 1, so we return 1.

Constraints:

  • 1 <= nums.length <= 105
  • 1 <= nums[i], k <= 105

Hard,线段树

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
class Solution {
vector<int> max;

void modify(int o, int l, int r, int i, int val) {
if (l == r) {
max[o] = val;
return;
}
int m = (l + r) / 2;
if (i <= m) modify(o * 2, l, m, i, val);
else modify(o * 2 + 1, m + 1, r, i, val);
max[o] = std::max(max[o * 2], max[o * 2 + 1]);
}

// 返回区间 [L,R] 内的最大值
int query(int o, int l, int r, int L, int R) { // L 和 R 在整个递归过程中均不变,将其大写,视作常量
if (L <= l && r <= R) return max[o];
int res = 0;
int m = (l + r) / 2;
if (L <= m) res = query(o * 2, l, m, L, R);
if (R > m) res = std::max(res, query(o * 2 + 1, m + 1, r, L, R));
return res;
}

public:
int lengthOfLIS(vector<int> &nums, int k) {
int u = *max_element(nums.begin(), nums.end());
max.resize(u * 4);
for (int num: nums) {
if (num == 1) modify(1, 1, u, 1, 1);
else {
int res = 1 + query(1, 1, u, std::max(num - k, 1), num - 1);
modify(1, 1, u, num, res);
}
}
return max[1];
}
};

Weekly Contest 311

image-20220919090430242

2413. Smallest Even Multiple

Given a positive integer n, return the smallest positive integer that is a multiple of both 2 and n.

Example 1:

1
2
3
Input: n = 5
Output: 10
Explanation: The smallest multiple of both 5 and 2 is 10.

Example 2:

1
2
3
Input: n = 6
Output: 6
Explanation: The smallest multiple of both 6 and 2 is 6. Note that a number is a multiple of itself.

Constraints:

  • 1 <= n <= 150

Easy,查看是否是偶数

1
2
3
4
5
6
7
8
9
10
class Solution {
public:
int smallestEvenMultiple(int n) {
if (n % 2 == 0) {
return n;
} else {
return 2 * n;
}
}
};

2414. Length of the Longest Alphabetical Continuous Substring

An alphabetical continuous string is a string consisting of consecutive letters in the alphabet. In other words, it is any substring of the string "abcdefghijklmnopqrstuvwxyz".

  • For example, "abc" is an alphabetical continuous string, while "acb" and "za" are not.

Given a string s consisting of lowercase letters only, return the length of the longest alphabetical continuous substring.

Example 1:

1
2
3
4
Input: s = "abacaba"
Output: 2
Explanation: There are 4 distinct continuous substrings: "a", "b", "c" and "ab".
"ab" is the longest continuous substring.

Example 2:

1
2
3
Input: s = "abcde"
Output: 5
Explanation: "abcde" is the longest continuous substring.

Constraints:

  • 1 <= s.length <= 105
  • s consists of only English lowercase letters.

Medium,滑动窗口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public:
int longestContinuousSubstring(string s) {
int res = 1;
int pre = 0;
int cur = 1;
while (cur < s.size()) {
while (cur < s.size() && s[cur] - s[cur - 1] == 1) {
cur++;
}
res = max(res, cur - pre);
pre = cur;
cur++;
}
return res;
}
};

2415. Reverse Odd Levels of Binary Tree

Given the root of a perfect binary tree, reverse the node values at each odd level of the tree.

  • For example, suppose the node values at level 3 are [2,1,3,4,7,11,29,18], then it should become [18,29,11,7,4,3,1,2].

Return the root of the reversed tree.

A binary tree is perfect if all parent nodes have two children and all leaves are on the same level.

The level of a node is the number of edges along the path between it and the root node.

Example 1:

img

1
2
3
4
5
Input: root = [2,3,5,8,13,21,34]
Output: [2,5,3,8,13,21,34]
Explanation:
The tree has only one odd level.
The nodes at level 1 are 3, 5 respectively, which are reversed and become 5, 3.

Example 2:

img

1
2
3
4
Input: root = [7,13,11]
Output: [7,11,13]
Explanation:
The nodes at level 1 are 13, 11, which are reversed and become 11, 13.

Example 3:

1
2
3
4
5
6
Input: root = [0,1,2,0,0,0,0,1,1,1,1,2,2,2,2]
Output: [0,2,1,0,0,0,0,2,2,2,2,1,1,1,1]
Explanation:
The odd levels have non-zero values.
The nodes at level 1 were 1, 2, and are 2, 1 after the reversal.
The nodes at level 3 were 1, 1, 1, 1, 2, 2, 2, 2, and are 2, 2, 2, 2, 1, 1, 1, 1 after the reversal.

Constraints:

  • The number of nodes in the tree is in the range [1, 214].
  • 0 <= Node.val <= 105
  • root is a perfect binary tree.

Medium,BFS 层次遍历

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
41
42
43
44
45
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* reverseOddLevels(TreeNode* root) {
int level = 0;
queue<TreeNode*> q;
q.push(root);
while (!q.empty()) {
level++;
int sz = q.size();
vector<int> res(sz);
queue<TreeNode*> qLevel;
for (int i = 0; i < sz; i++) {
TreeNode* node = q.front();
res[i] = node->val;
qLevel.push(node);
q.pop();
if (node->left) {
q.push(node->left);
}
if (node->right) {
q.push(node->right);
}
}
if (level % 2 == 0) {
for (int i = 0; i < sz; i++) {
TreeNode* node = qLevel.front();
node->val = res[sz - 1 - i];
qLevel.pop();
}
}
}
return root;
}
};

Failed: 2416. Sum of Prefix Scores of Strings

You are given an array words of size n consisting of non-empty strings.

We define the score of a string word as the number of strings words[i] such that word is a prefix of words[i].

  • For example, if words = ["a", "ab", "abc", "cab"], then the score of "ab" is 2, since "ab" is a prefix of both "ab" and "abc".

Return an array answer of size n where answer[i] is the sum of scores of every non-empty prefix of words[i].

Note that a string is considered as a prefix of itself.

Example 1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Input: words = ["abc","ab","bc","b"]
Output: [5,4,3,2]
Explanation: The answer for each string is the following:
- "abc" has 3 prefixes: "a", "ab", and "abc".
- There are 2 strings with the prefix "a", 2 strings with the prefix "ab", and 1 string with the prefix "abc".
The total is answer[0] = 2 + 2 + 1 = 5.
- "ab" has 2 prefixes: "a" and "ab".
- There are 2 strings with the prefix "a", and 2 strings with the prefix "ab".
The total is answer[1] = 2 + 2 = 4.
- "bc" has 2 prefixes: "b" and "bc".
- There are 2 strings with the prefix "b", and 1 string with the prefix "bc".
The total is answer[2] = 2 + 1 = 3.
- "b" has 1 prefix: "b".
- There are 2 strings with the prefix "b".
The total is answer[3] = 2.

Example 2:

1
2
3
4
5
Input: words = ["abcd"]
Output: [4]
Explanation:
"abcd" has 4 prefixes: "a", "ab", "abc", and "abcd".
Each prefix has a score of one, so the total is answer[0] = 1 + 1 + 1 + 1 = 4.

Constraints:

  • 1 <= words.length <= 1000
  • 1 <= words[i].length <= 1000
  • words[i] consists of lowercase English letters.

Hard,前缀树

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
class Trie {
public:
Trie *ch[26] = {};
int visited = 0;
};
class Solution {
public:
vector<int> sumPrefixScores(vector<string>& words) {
Trie trie;
vector<int> ans;
for (string& word: words) {
auto t = &trie;
for (char& c: word) {
if (!t->ch[c - 'a']) t->ch[c - 'a'] = new Trie();
t->ch[c - 'a']->visited++;
t = t->ch[c - 'a'];
}
}
for (string& word: words) {
auto t = &trie;
int cur = 0;
for (char& c: word) {
cur += t->ch[c - 'a']->visited;
t = t->ch[c - 'a'];
}
ans.push_back(cur);
}
return ans;
}
};

Weekly Contest 312

image-20220925135159723

2418. Sort the People

You are given an array of strings names, and an array heights that consists of distinct positive integers. Both arrays are of length n.

For each index i, names[i] and heights[i] denote the name and height of the ith person.

Return names sorted in descending order by the people’s heights.

Example 1:

1
2
3
Input: names = ["Mary","John","Emma"], heights = [180,165,170]
Output: ["Mary","Emma","John"]
Explanation: Mary is the tallest, followed by Emma and John.

Example 2:

1
2
3
Input: names = ["Alice","Bob","Bob"], heights = [155,185,150]
Output: ["Bob","Alice","Bob"]
Explanation: The first Bob is the tallest, followed by Alice and the second Bob.

Constraints:

  • n == names.length == heights.length
  • 1 <= n <= 103
  • 1 <= names[i].length <= 20
  • 1 <= heights[i] <= 105
  • names[i] consists of lower and upper case English letters.
  • All the values of heights are distinct.

Easy,排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public:
vector<string> sortPeople(vector<string>& names, vector<int>& heights) {
vector<pair<int, int>> heightS;
for (int i = 0; i < heights.size(); i++) {
heightS.push_back({heights[i], i});
}
sort(heightS.begin(), heightS.end());
vector<string> res;
for (int i = heights.size() - 1; i >= 0; i--) {
res.push_back(names[heightS[i].second]);
}
return res;
}
};

或者参考别人的

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
struct Person {
string name;
int height;
};

class Solution {
public:
vector<string> sortPeople(vector<string>& names, vector<int>& heights) {
vector<Person> people;
for (int i = 0; i < names.size(); i++) {
Person p{names[i], heights[i]};
people.push_back(p);
}

std::sort(people.begin(), people.end(), [](const Person & a, const Person & b) -> bool {
return b.height < a.height + 1;
});

vector<string> res;
for (Person p : people) {
res.push_back(p.name);
}
return res;
}
};

2419. Longest Subarray With Maximum Bitwise AND

You are given an integer array nums of size n.

Consider a non-empty subarray from nums that has the maximum possible bitwise AND.

  • In other words, let k be the maximum value of the bitwise AND of any subarray of nums. Then, only subarrays with a bitwise AND equal to k should be considered.

Return the length of the longest such subarray.

The bitwise AND of an array is the bitwise AND of all the numbers in it.

A subarray is a contiguous sequence of elements within an array.

Example 1:

1
2
3
4
5
Input: nums = [1,2,3,3,2,2]
Output: 2
Explanation:
The maximum possible bitwise AND of a subarray is 3.
The longest subarray with that value is [3,3], so we return 2.

Example 2:

1
2
3
4
5
Input: nums = [1,2,3,4]
Output: 1
Explanation:
The maximum possible bitwise AND of a subarray is 4.
The longest subarray with that value is [4], so we return 1.

Constraints:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 106

Medium,翻译一下就是最大数的最长长度

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
class Solution {
public:
int longestSubarray(vector<int>& nums) {
int maxVal = 0;
int maxLen = 1;
for (int i = 0; i < nums.size(); ) {
if (nums[i] >= maxVal) {
int j = i + 1;
while (j < nums.size() && nums[j] == nums[i]) {
j++;
}
if (maxVal == nums[i]) {
maxLen = max(maxLen, j - i);
} else {
maxLen = j - i;
}
maxVal = nums[i];
i = j;
} else {
i++;
}
}
return maxLen;
}
};

2420. Find All Good Indices

You are given a 0-indexed integer array nums of size n and a positive integer k.

We call an index i in the range k <= i < n - k good if the following conditions are satisfied:

  • The k elements that are just before the index i are in non-increasing order.
  • The k elements that are just after the index i are in non-decreasing order.

Return an array of all good indices sorted in increasing order.

Example 1:

1
2
3
4
5
6
Input: nums = [2,1,1,1,3,4,1], k = 2
Output: [2,3]
Explanation: There are two good indices in the array:
- Index 2. The subarray [2,1] is in non-increasing order, and the subarray [1,3] is in non-decreasing order.
- Index 3. The subarray [1,1] is in non-increasing order, and the subarray [3,4] is in non-decreasing order.
Note that the index 4 is not good because [4,1] is not non-decreasing.

Example 2:

1
2
3
Input: nums = [2,1,1,2], k = 2
Output: []
Explanation: There are no good indices in this array.

Constraints:

  • n == nums.length
  • 3 <= n <= 105
  • 1 <= nums[i] <= 106
  • 1 <= k <= n / 2

Medium,使用动态规划计算当前元素结尾递增/递减数组长度,

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
class Solution {
public:
vector<int> goodIndices(vector<int>& nums, int k) {
int n = nums.size();
vector<int> dec(n, 1);
vector<int> inc(n, 1);
for (int i = 1; i < n; i++) {
if (nums[i] > nums[i - 1]) {
inc[i] = inc[i - 1] + 1;
} else if (nums[i] < nums[i - 1]) {
dec[i] = dec[i - 1] + 1;
} else {
inc[i] = inc[i - 1] + 1;
dec[i] = dec[i - 1] + 1;
}
}
vector<int> res;
for (int i = k; i + k < n; i++) {
if (dec[i - 1] >= k && inc[i + k] >= k ) {
res.push_back(i);
}
}
return res;
}
};

Failed: 2421. Number of Good Paths

There is a tree (i.e. a connected, undirected graph with no cycles) consisting of n nodes numbered from 0 to n - 1 and exactly n - 1 edges.

You are given a 0-indexed integer array vals of length n where vals[i] denotes the value of the ith node. You are also given a 2D integer array edges where edges[i] = [ai, bi] denotes that there exists an undirected edge connecting nodes ai and bi.

A good path is a simple path that satisfies the following conditions:

  1. The starting node and the ending node have the same value.
  2. All nodes between the starting node and the ending node have values less than or equal to the starting node (i.e. the starting node’s value should be the maximum value along the path).

Return the number of distinct good paths.

Note that a path and its reverse are counted as the same path. For example, 0 -> 1 is considered to be the same as 1 -> 0. A single node is also considered as a valid path.

Example 1:

img

1
2
3
4
5
6
Input: vals = [1,3,2,1,3], edges = [[0,1],[0,2],[2,3],[2,4]]
Output: 6
Explanation: There are 5 good paths consisting of a single node.
There is 1 additional good path: 1 -> 0 -> 2 -> 4.
(The reverse path 4 -> 2 -> 0 -> 1 is treated as the same as 1 -> 0 -> 2 -> 4.)
Note that 0 -> 2 -> 3 is not a good path because vals[2] > vals[0].

Example 2:

img

1
2
3
4
Input: vals = [1,1,2,2,3], edges = [[0,1],[1,2],[2,3],[2,4]]
Output: 7
Explanation: There are 5 good paths consisting of a single node.
There are 2 additional good paths: 0 -> 1 and 2 -> 3.

Example 3:

img

1
2
3
Input: vals = [1], edges = []
Output: 1
Explanation: The tree consists of only one node, so there is one good path.

Constraints:

  • n == vals.length
  • 1 <= n <= 3 * 104
  • 0 <= vals[i] <= 105
  • edges.length == n - 1
  • edges[i].length == 2
  • 0 <= ai, bi < n
  • ai != bi
  • edges represents a valid tree.

Hard,并查集

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
41
42
43
44
45
class Solution {
public:
int numberOfGoodPaths(vector<int>& vals, vector<vector<int>>& edges) {
int n = vals.size();
// 建图
vector<vector<int>> graph(n);
for (vector<int>& edge: edges) {
graph[edge[0]].push_back(edge[1]);
graph[edge[1]].push_back(edge[0]);
}
// 并查集模板
// size[x] 表示节点值等于 vals[x] 的节点个数,如果按照节点值从小到大合并,size[x] 也是连通块内的等于最大节点值的节点个数

int id[n], fa[n], size[n]; // id 后面排序用
iota(id, id + n, 0);
iota(fa, fa + n, 0);
fill(size, size + n, 1);
function<int(int)> find = [&](int x) -> int {
return fa[x] == x ? x : fa[x] = find(fa[x]);
};

int ans = n;
sort(id, id + n, [&](int i, int j) {
return vals[i] < vals[j];
});
for (int x : id) {
int vx = vals[x], fx = find(x);
for (int y : graph[x]) {
y = find(y);
// 只考虑最大节点值比 vx 小的连通块
if (y == fx || vals[y] > vx) continue;
// 可以构成好路径
if (vals[y] == vx) {
// 乘法原理
ans += size[fx] * size[y];
// 统计连通块内节点值等于 vx 的节点个数
size[fx] += size[y];
}
// 把小的节点值合并到大的节点值上
fa[y] = fx;
}
}
return ans;
}
};

Weekly Contest 312

image-20221002154624485

2427. Number of Common Factors

Given two positive integers a and b, return the number of common factors of a and b.

An integer x is a common factor of a and b if x divides both a and b.

Example 1:

1
2
3
Input: a = 12, b = 6
Output: 4
Explanation: The common factors of 12 and 6 are 1, 2, 3, 6.

Example 2:

1
2
3
Input: a = 25, b = 30
Output: 2
Explanation: The common factors of 25 and 30 are 1, 5.

Constraints:

  • 1 <= a, b <= 1000

Easy,最大公约数,应有更好的方法,找到后分解质因数

1
2
3
4
5
6
7
8
9
10
11
class Solution {
public:
int commonFactors(int a, int b) {
int num = std::gcd(a, b);
int res = 1;
for (int i = 2; i <= num; i++) {
if (num % i == 0) res++;
}
return res;
}
};

2428. Maximum Sum of an Hourglass

You are given an m x n integer matrix grid.

We define an hourglass as a part of the matrix with the following form:

img

Return the maximum sum of the elements of an hourglass.

Note that an hourglass cannot be rotated and must be entirely contained within the matrix.

Example 1:

img

1
2
3
Input: grid = [[6,2,1,3],[4,2,1,5],[9,2,8,7],[4,1,2,9]]
Output: 30
Explanation: The cells shown above represent the hourglass with the maximum sum: 6 + 2 + 1 + 2 + 9 + 2 + 8 = 30.

Example 2:

img

1
2
3
Input: grid = [[1,2,3],[4,5,6],[7,8,9]]
Output: 35
Explanation: There is only one hourglass in the matrix, with the sum: 1 + 2 + 3 + 5 + 7 + 8 + 9 = 35.

Constraints:

  • m == grid.length
  • n == grid[i].length
  • 3 <= m, n <= 150
  • 0 <= grid[i][j] <= 106

Medium,直接计算每个窗口之和,理论上可以使用滑动窗口优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public:
int maxSum(vector<vector<int>>& grid) {
int m = grid.size(), n = grid[0].size();
int res = 0;
for (int i = 0; i < m - 2; i++) {
for (int j = 0; j < n - 2; j++) {
int num = grid[i][j] + grid[i][j + 1] + grid[i][j + 2] + grid[i + 1][j + 1] + grid[i + 2][j] + grid[i + 2][j + 1] + grid[i + 2][j + 2];
if (num > res) res = num;
}
}
return res;
}
};

2429. Minimize XOR

Given two positive integers num1 and num2, find the integer x such that:

  • x has the same number of set bits as num2, and
  • The value x XOR num1 is minimal.

Note that XOR is the bitwise XOR operation.

Return the integer x. The test cases are generated such that x is uniquely determined.

The number of set bits of an integer is the number of 1‘s in its binary representation.

Example 1:

1
2
3
4
5
Input: num1 = 3, num2 = 5
Output: 3
Explanation:
The binary representations of num1 and num2 are 0011 and 0101, respectively.
The integer 3 has the same number of set bits as num2, and the value 3 XOR 3 = 0 is minimal.

Example 2:

1
2
3
4
5
Input: num1 = 1, num2 = 12
Output: 3
Explanation:
The binary representations of num1 and num2 are 0001 and 1100, respectively.
The integer 3 has the same number of set bits as num2, and the value 3 XOR 1 = 2 is minimal.

Constraints:

  • 1 <= num1, num2 <= 109

Medium,位计算

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class Solution {
public:
int minimizeXor(int num1, int num2) {
vector<int> bin1(31, 0), bin2(31, 0);
getBin(num1, bin1);
getBin(num2, bin2);
int count1 = std::accumulate(bin1.begin(), bin1.end(), 0);
int count2 = std::accumulate(bin2.begin(), bin2.end(), 0);
if (count1 == count2) return num1;
vector<int> bin = bin1;
if (count1 < count2) {
int diff = count2 - count1;
for (int i = 0; i < 31; i++) {
if (bin1[i] == 0) {
bin[i] = 1;
diff--;
if (diff == 0) {
break;
}
}
}
} else {
int diff = count1 - count2;
for (int i = 0; i < 31; i++) {
if (bin1[i] == 1) {
bin[i] = 0;
diff--;
if (diff == 0) {
break;
}
}
}
}
return genNum(bin);
}
void getBin(int num, vector<int> &bin) {
int count = 0;
while (num != 0) {
bin[count] = num & 1;
count++;
num = num >> 1;
}
}
int genNum(vector<int> &bin) {
int res = 0, cur = 1;
for (int i = 0; i < 31; i++) {
if (bin[i] == 1) {
res = res | cur;
}
cur = cur << 1;
}
return res;
}
};

同样的逻辑,看看人大佬写得多优雅

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public:
int minimizeXor(int num1, int num2) {
int a = __builtin_popcount(num1), b = __builtin_popcount(num2), res = num1;
for (int i = 0; i < 32; ++i) {
if (a > b && ((1 << i) & num1) > 0) {
res ^= 1 << i;
a--;
}
if (a < b && ((1 << i) & num1) == 0) {
res ^= 1 << i;
a++;
}
}
return res;
}
};

2430. Maximum Deletions on a String

You are given a string s consisting of only lowercase English letters. In one operation, you can:

  • Delete the entire string s, or
  • Delete the first i letters of s if the first i letters of s are equal to the following i letters in s, for any i in the range 1 <= i <= s.length / 2.

For example, if s = "ababc", then in one operation, you could delete the first two letters of s to get "abc", since the first two letters of s and the following two letters of s are both equal to "ab".

Return the maximum number of operations needed to delete all of s.

Example 1:

1
2
3
4
5
6
7
Input: s = "abcabcdabc"
Output: 2
Explanation:
- Delete the first 3 letters ("abc") since the next 3 letters are equal. Now, s = "abcdabc".
- Delete all the letters.
We used 2 operations so return 2. It can be proven that 2 is the maximum number of operations needed.
Note that in the second operation we cannot delete "abc" again because the next occurrence of "abc" does not happen in the next 3 letters.

Example 2:

1
2
3
4
5
6
7
8
Input: s = "aaabaab"
Output: 4
Explanation:
- Delete the first letter ("a") since the next letter is equal. Now, s = "aabaab".
- Delete the first 3 letters ("aab") since the next 3 letters are equal. Now, s = "aab".
- Delete the first letter ("a") since the next letter is equal. Now, s = "ab".
- Delete all the letters.
We used 4 operations so return 4. It can be proven that 4 is the maximum number of operations needed.

Example 3:

1
2
3
Input: s = "aaaaa"
Output: 5
Explanation: In each operation, we can delete the first letter of s.

Constraints:

  • 1 <= s.length <= 4000
  • s consists only of lowercase English letters.

Hard,ts暴力可解

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
41
42
43
44
45
46
47
48
function dup(s: string): boolean {
const len = s.length;
for (let i = 1; i <= Math.floor(len / 2); i++) {
if (len % i == 0) {
let t = s.slice(0, i);
let j = len / i;
if (s === t.repeat(j)) {
return true;
}
}
}
return false;
}

function deleteString(s: string): number {
let res: number = 0;
while (s.length > 0) {
const len = s.length;
if (dup(s)) {
for (let i = 1; i <= Math.floor(len / 2); i++) {
if (len % i == 0) {
let t = s.slice(0, i);
let j = len / i;
if (s === t.repeat(j)) {
s = t;
res += j - 1;
break;
}
}
}
} else {
let i = Math.floor(len / 2);
for (; i >= 1; i--) {
const t = s.slice(0, i);
if (s.startsWith(t + t) && !dup(t)) {
s = s.slice(i);
res++;
break;
}
}
if (i == 0) {
res++;
break;
}
}
}
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
41
42
class Solution {
public:
bool isValid(int first, int second, string &s){
int i = first;
int j = second;
int n = s.length();
while (i < second) {
if (s[i] == s[j]) {
i++;
j++;
} else {
return false;
}
if (j == n && i < second)
return false;
}
return true;
}
int deleteString(string s) {
int n = s.length();
int dp[n];
dp[n - 1] = 1;
unordered_map<char, vector<int>> temp;
temp[s[n - 1]] = {n - 1};
for (int i = n - 2; i >= 0; i--) {
if (temp.find(s[i]) == temp.end()) {
dp[i] = 1;
temp[s[i]] = {i};
} else {
vector<int> st = temp[s[i]];
int maximum = 0;
for (int j = st.size() - 1; j >= 0; j--) {
if (dp[st[j]] > maximum && isValid(i, st[j], s))
maximum = dp[st[j]];
}
dp[i] = maximum + 1;
temp[s[i]].push_back(i);
}
}
return dp[0];
}
};
-------------本文结束感谢您的阅读-------------

欢迎关注我的其它发布渠道