第 110 场力扣双周赛题解

A 取整购买后的账户余额

第 110 场力扣双周赛题解_第1张图片

签到题

class Solution {
public:
    int accountBalanceAfterPurchase(int purchaseAmount) {
        return purchaseAmount % 10 < 5 ? 100 - purchaseAmount / 10 * 10 : 100 - (purchaseAmount / 10 + 1) * 10;
    }
};

B 在链表中插入最大公约数

第 110 场力扣双周赛题解_第2张图片

模拟:从链表头开始处理,只要有至少两个节点就插入一个新的节点,同时后移正在遍历的指针

class Solution {
public:
    ListNode *insertGreatestCommonDivisors(ListNode *head) {
        for (ListNode *cur = head; cur->next;) {//在cur和cur-next之间插入节点
            ListNode *t = new ListNode(gcd(cur->val, cur->next->val), cur->next);
            cur->next = t;
            cur = cur->next->next;
        }
        return head;
    }
};

C 使循环数组所有元素相等的最少秒数

第 110 场力扣双周赛题解_第3张图片

哈希+枚举:设数 x x x在数组中出现的所有位置下标为升序排列为: l o c 0 , l o c 1 , ⋯   , l o c k − 1 loc_0,loc_1,\cdots,loc_{k-1} loc0,loc1,,lock1, 设 l o c j loc_j locj l o c ( j − 1 + k ) % k loc_{(j-1+k)\%k} loc(j1+k)%k之间的间隔为 d j d_j dj,考虑一个长为 d d d的间隔,要把间隔内的数都替换为 x x x的最少时间为 ⌈ d 2 ⌉ \left \lceil \frac {d} 2 \right \rceil 2d,所有要把所有间隔内的数都替换为 x x x的最少时间为: m a x { ⌈ d j 2 ⌉    ∣    0 ≤ j < k } max\{ \left \lceil \frac {d_j} 2 \right \rceil \; | \; 0\le j< k \} max{2dj0j<k}。用哈希记录数组中每个数出现的所有位置下标,然后枚举不同的每个数。

class Solution {
public:
    inline int cmp(int x) {//间隔长为x需要的时间
        return (x + 1) / 2;
    }

    int minimumSeconds(vector<int> &nums) {
        unordered_map<int, vector<int>> li;//哈希表
        int n = nums.size();
        for (int i = 0; i < n; i++)
            li[nums[i]].push_back(i);
        int res = INT32_MAX;
        for (auto &[_, loc]: li) {//枚举不同的每个数
            int t = 0;
            for (int i = 0; i < loc.size() - 1; i++)
                t = max(t, cmp(loc[i + 1] - loc[i] - 1));
            t = max(t, cmp(loc.front() + n - loc.back() - 1));//最后一个位置右边和第一个位置的左边形成的间隔
            res = min(res, t);
        }
        return res;
    }
};

D 使数组和小于等于 x 的最少时间

第 110 场力扣双周赛题解_第4张图片

动态规划:因为每个位置最多只需清零一次,所以若可以实现目标,最多需要时间为 n n n n n n n u m s 1 nums1 nums1的长度),考虑 j j j个单位时间内删除位置的下标依次为 a 1 , ⋯   , a j a_1,\cdots,a_j a1,,aj, 则 j j j个单位时间后 n u m s 1 nums1 nums1的数组和为: S 1 + S 2 × j − { ( n u m s 1 [ a 1 ] + n u m s 2 [ a 1 ] × 1 ) + ⋯ + ( n u m s 1 [ a j ] + n u m s 2 [ a j ] × j ) } S_1+S_2\times j-\{(nums1[a_1]+nums2[a_1]\times 1)+\cdots+(nums1[a_j]+nums2[a_j]\times j)\} S1+S2×j{(nums1[a1]+nums2[a1]×1)++(nums1[aj]+nums2[aj]×j)},其中 S 1 S_1 S1 S 2 S_2 S2 n u m s 1 nums1 nums1 n u m s 2 nums2 nums2的初始数组和。可以发现若 j j j个单位时间内删除位置的集合固定,则可以确定最优的清零顺序(使得方括号内的和最大):即将 j j j个单位时间内删除位置按 n u m s 2 nums2 nums2中对应的值升序排列。因为具有这个特点所以可以使用动态规划来求方括号内的和的最大值,首先将 n u m s 1 nums1 nums1 n u m s 2 nums2 nums2 n u m s 2 nums2 nums2的值升序排序,然后定义状态 p i , j p_{i,j} pi,j为前 i i i个位置内选择 j j j个位置清零能清零的最大和,有状态转移方程: p i , j = m a x { p i , j − 1 p i − 1 , j − 1 + ( n u m s 1 [ i − 1 ] + n u m s 2 [ i − 1 ] × j ) p_{i,j}=max\left\{\begin{matrix} p_{i,j-1} \\ p_{i-1,j-1} + (nums1[i-1]+nums2[i-1]\times j) & \end{matrix}\right. pi,j=max{pi,j1pi1,j1+(nums1[i1]+nums2[i1]×j)
最后枚举枚举经过时间 a n s ans ans,判断 S 1 + S 2 × r e s − p n , r e s ≤ x S_1 + S_2 \times res - p_{n,res} \le x S1+S2×respn,resx是否成立。

class Solution {
public:
    int minimumTime(vector<int> &nums1, vector<int> &nums2, int x) {
        int n = nums1.size();
        vector<pair<int, int>> li(n);
        int s1 = 0, s2 = 0;//初始数组和
        for (int i = 0; i < n; i++) {
            li[i] = {nums1[i], nums2[i]};
            s1 += nums1[i];
            s2 += nums2[i];
        }
        sort(li.begin(), li.end(), [](const pair<int, int> &a, const pair<int, int> &b) {//按nums2中的值升序排序
            return a.second < b.second;
        });
        int p[n + 1][n + 1];
        p[0][0] = 0;//清零0个位置的最大和为0
        for (int i = 1; i <= n; i++) {
            p[i][0] = 0;
            for (int j = 1; j <= i; j++) {
                p[i][j] = p[i - 1][j - 1] + li[i - 1].first + li[i - 1].second * j;
                if (i - 1 >= j)
                    p[i][j] = max(p[i][j], p[i - 1][j]);
            }
        }
        for (int res = 0; res <= n; res++)
            if (s1 + s2 * res - p[n][res] <= x)
                return res;
        return -1;
    }
};

你可能感兴趣的:(LeetCode,leetcode,算法,链表,哈希,动态规划,排序)