LeetCode game 275

Posted by illuz1on on Sun, 09 Jan 2022 07:34:57 +0100

5976. Check whether each row and column contain all integers

Title Description: give you a \ (n \times n \) matrix to judge whether each row and column contain all integers from \ (1\sim n \), which returns true, otherwise it returns false.

Idea: directly simulate according to the meaning of the topic

Time complexity: \ (O(n^2) \)

Reference code:

class Solution {
public:
bool checkValid(vector<vector<int>>& matrix) {
int n = matrix.size();
//Check whether the line meets
for(int i = 0 ; i < n ; ++i){
vector<int> cnt(n , 1);
for(int num : matrix[i]){
if(--cnt[num - 1] < 0) return false;
}
}
//Inspection column
for(int j = 0 ; j < n ; ++j){
vector<int>cnt(n , 1);
for(int i = 0 ; i < n ; ++i){
if(--cnt[matrix[i][j] - 1] < 0) return  false;
}
}
return true;
}
};

5977. Combine all 1 II with the minimum number of exchanges

Topic Description: exchange is defined as selecting two different positions in an array and exchanging their values. A ring array is an array in which the first element and the last element can be considered adjacent. Give you a binary ring array \ (Num \), which returns the minimum number of exchanges required to gather all \ (1 \) in the array at any position.

Idea: obviously, the answer has only two forms: 0011100 and 11000111. For the second, it is equivalent to aggregating 0 in a non-circular array. For aggregation in a non ring array, the minimum number of times required is the total number of 1 minus the number of 1 in a window with a length of \ (1 \).

Time complexity: \ (O(n) \)

Space complexity: \ (O(n) \)

Reference code:

class Solution {
private:
int solve(vector<int>& nums){
int n = nums.size() , cnt = 0;
for(auto num : nums) cnt += num == 1;
int res = n, presum = 0;
for(int i = 0 ; i < n ; ++i){
presum += nums[i] == 1;
if(i >= cnt) presum -= nums[i - cnt] == 1;
if(i >= cnt - 1) res = min(res , cnt - presum);
}
return res;
}
public:
int minSwaps(vector<int>& nums) {
int res = solve(nums);
for(auto& num : nums) num^= 1;
res = min(res, solve(nums));
return res;
}
};

5978. Count the number of words that can be obtained by adding letters

Title Description: give you two string arrays with subscripts starting from 0, startWords and targetWords. Each string consists of only lowercase English letters. For each string in targetWords, check whether a string can be selected from startWords, perform a conversion operation, and the result is equal to the current targetWords string.

The conversion operation is: add a character that does not currently appear in the string, and then add it to the end. Then perform any rearrangement.

Find out how many strings in targetWords can be obtained by performing the above conversion operation on any string in startWords. Returns the number of such strings in targetWords.

Idea: obviously, you can enumerate all the strings that can be converted from all the strings in startWords, and then insert them into the set in order of characters from small to large. Then traverse targetWords, sort the strings from small to large, and find them in the set. If the size of the character set is \ (\ sum \), the time complexity of this method is: \ (O(26\sum log\sum) \) and the constant is huge. The last point of timeout in the actual measurement. Considering optimization, it is noted that each character in each string occurs only once, and there are only 26 characters, so consider using binary to represent each character. A string is an integer of type \ (int \). Assuming that there are \ (n \) strings, the time complexity of doing so is: \ (O(\sum + 26\times nlogn) \) can pass this question.

Time complexity: \ (O(\sum + 26 \times nlogn) \)

Reference code:

class Solution {
public:
int wordCount(vector<string>& startWords, vector<string>& targetWords) {
set<int> s;
for(auto& str : startWords){
vector<int> cnt(26 , 0);
for(auto c : str) cnt[c - 'a']++;
int dx = 0;
for(int i = 0 ; i < 26 ; ++i) if(cnt[i]) dx |= 1 << i;
for(int i = 0 ; i < 26 ; ++i){
if(cnt[i]) continue;
int dy = dx + (1 << i);
s.insert(dy);
}
}
int res = 0;
for(auto& str : targetWords){
vector<int> cnt(26 , 0);
for(auto c : str) cnt[c - 'a']++;
int dx = 0;
for(int i = 0 ; i < 26 ; ++i) if(cnt[i]) dx |= 1 << i;
if(s.find(dx) != s.end()) ++res;
}
return res;
}
};

Code when not optimized:

class Solution {
public:
int wordCount(vector<string>& startWords, vector<string>& targetWords) {
set<string> s;
for(auto& str : startWords){
vector<int> cnt(26 , 0);
for(auto c : str) cnt[c - 'a']++;
for(int i = 0 ; i < 26 ; ++i){
if(cnt[i]) continue;
string t = str;
t += 'a' + i;
sort(t.begin() , t.end());
s.insert(t);
}
}
int res = 0;
for(auto& str : targetWords){
sort(str.begin() , str.end());
if(s.find(str) != s.end()) ++res;
}
return res;
}
};

5979. The earliest day of full flowering

Title Description: give you \ (n \) seeds. Each seed must be planted before it can begin to grow and blossom. Sowing takes time, and so does the growth of seeds. Give you two integer arrays plantTime and growTime with subscripts starting from \ (0 \), and the length of each array is \ (n \):

• plantTime[i] is the complete number of days required to sow the \ (I \) seed. Every day, you can only work for sowing a seed. It is not necessary to plant the same seed for several consecutive days, but the seed sowing must be completed after your working days reach plantTime[i].
• Growth time [i] is the complete number of days required for the growth of the ith seed after it is completely planted. After the last day of its growth, it will bloom and bloom forever.

From day \ (0 \), you can plant seeds in any order to find the earliest time when all seeds bloom.

Idea: obviously, to make the time as early as possible, it is necessary to make the sowing time of the currently sown seeds coincide with the growth time of the previously sown seeds as much as possible. Therefore, the seeds with long growth time should be placed in front, that is, they should be sorted from large to small according to the growth time of seeds, and then sown.

Time complexity: \ (O(nlogn) \)

Reference code:

class Solution {
public:
int earliestFullBloom(vector<int>& plantTime, vector<int>& growTime) {
vector<pair<int , int>> nums;
int n = plantTime.size();
for(int i = 0 ; i < n ; ++i){
nums.push_back({plantTime[i] , growTime[i]});
}
std::sort(nums.begin() , nums.end() , [&](const pair<int , int>& a , const pair<int , int>& b){
return a.second > b.second;
});
int res = 0, curTime = 0;
for(auto& num : nums){
res = max(res , curTime + num.first + num.second);
curTime += num.first;
}
return res;
}
};

Topics: greedy algorithm