LeetCode 71 Biweekly Game

Posted by sayoko on Sat, 05 Feb 2022 18:34:23 +0100

Title Description: Give you a four-digit integer to rearrange the numbers in this integer and divide them into two parts, allowing leading$$0$$. Ask the minimum value of the sum in decimal representation of the two parts.

Thought: Simulate according to the title,

Time Complexity: $$O(1)$$

Reference code:

class Solution {
public:
int minimumSum(int num) {
string s = to_string(num);
vector<int>cnt(10 , 0);
for(auto c : s) cnt[c - '0'] ++;
int res = 0, dx = 0 , ct = 0;
for(int i = 0 ; i < 10 ; ++i){
if(cnt[i] == 0) continue;
while(cnt[i]){
if(ct < 2) res += i * 10;
else res += i;
--cnt[i];
++ct;
}
}
return res;
}
};


Title Description: Give you an array $$nums$$ of length $$n$$, and a dividing number $$x$$, so that you can put numbers less than $$x$$ in the array to the left of all $$x$$ without changing their original relative order, and numbers greater than $$x$$ in the array to the right of all $$x$$ without changing their original relative order.

Idea: Simulate according to the title.

Time Complexity: $$O(n)$$

Reference code:

class Solution {
public:
vector<int> pivotArray(vector<int>& nums, int pivot) {
vector<int>res , rs;
int cnt = 0;
for(auto num : nums){
if(num < pivot) res.push_back(num);
else if(num == pivot) ++cnt;
else rs.push_back(num);
}
for(int i = 1 ; i <= cnt ; ++i) res.push_back(pivot);
for(auto num : rs) res.push_back(num);
return res;
}
};


Title Description: Look at the title yourself

Ideas: According to the meaning of the topic, first express the time as $$m: s$$ in which $$s < 60$$, and note that there may be $$m > 99$$ cases, which require special judgment. It is then expressed as a $$4$$ bit, and the value is calculated after removing the leading $$0$$. Then $$m \neq 0, s \leq 39$$ is represented as $$m-1: S + 60$$. Value is calculated once. Minimum of both is sufficient.

Time Complexity: $$O(1)$$

Reference code:

class Solution {
public:
int minCostSetTime(int startAt, int moveCost, int pushCost, int targetSeconds) {
auto solve = [&](vector<int>& target){
reverse(target.begin() , target.end());
while(target.back() == 0) target.pop_back();
reverse(target.begin() , target.end());
int cur = startAt, res = 0;
for(auto num : target){
if(num == cur) res += pushCost;
else res += pushCost + moveCost;
cur = num;
}
return res;
};
int m = targetSeconds / 60 , s = targetSeconds % 60;
if(m > 99) --m , s += 60;
vector<int>nums(4 , 0);
auto process = [&](vector<int>& nums , int m ,int s){
nums[0] = m / 10;nums[1] = m % 10;
nums[2] = s / 10; nums[3] = s % 10;
return ;
};
process(nums , m , s);
int res = solve(nums);
nums = vector<int>(4 , 0);
if(m && s <= 39){
--m;s += 60;
process(nums , m , s);
res = min(res , solve(nums));
}
return res;
}
};


Title Description: Give you an array of $$3 * n$$ length $$nums$$ so that you can delete $$n$$ of it. For deleted arrays, define the sum of the first $$n$$ digits to be $$sum_{first}$$, and the last $$n$$ digits to be $$sum {second}$$. Minimum value of $$sum_{first} - sum_{second}$$.

Idea: Obviously we want to minimize $$sum_{first}$$ and maximize $$sum_{second}$$. Consider defining the boundary point $$n - 1 \leq P < 2 *n$$. The interval [0, p] contains all the elements of the first part, and the largest $$p - n + 1$$ element is deleted according to the greedy policy, while the interval [p + 1, 3 * n - 1] contains all the elements of the second part. According to the greedy policy, the smallest elements of the second part are deleted: \$2 * n - p - 1. Consider how to maintain it. For the first part, use a large root heap. For the second part, we use two multiset a, b stores smaller $$2 * n - p - 1$$ elements and larger $$n$$ elements respectively. If the element corresponding to the moving boundary exists in a, it is deleted directly. Otherwise, it is deleted in b and the maximum value in a is added to b.

Time Complexity: $$O(nlogn)$$

Reference code:

class Solution {
public:
long long minimumDifference(vector<int>& nums) {
priority_queue<int>heap;
long long sum = 0;
int n = nums.size();
int m = n / 3;
for (int i = 0; i < m; ++i) {
sum += nums[i];
heap.push(nums[i]);
}
multiset<int> a, b;
for (int i = m; i < n; ++i) {
if (b.size() < m) {
sum -= nums[i];
b.insert(nums[i]);
}
else {
if (*b.begin() >= nums[i]) a.insert(nums[i]);
else {
int dx = *b.begin();
a.insert(*b.begin());
b.erase(b.begin());
b.insert(nums[i]);
sum += dx - nums[i];
}
}
}
long long res = sum;
for (int i = m; i < 2 * m; ++i) {
if (a.find(nums[i]) != a.end()) {
a.erase(a.find(nums[i]));
}
else {
b.erase(b.find(nums[i]));
int dx = *a.rbegin();
sum += nums[i] - dx;
b.insert(dx);
a.erase(a.find(dx));
}
if (nums[i] < heap.top()) {
sum -= heap.top();
heap.pop();
heap.push(nums[i]);
sum += nums[i];
}
res = min(res, sum);
}
return res;
}
};