LeetCode 71 Biweekly Game

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

Title Link Day Supplement

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;
    }
};