LeetCode 第 219 场周赛 题解

第 219 场周赛

关注我们,查看更多优质题解

题目1:5625. 比赛中的配对次数

思路:模拟

代码:

class Solution {
    
    
public:
    int numberOfMatches(int n) {
    
    
        int ret = 0;
        while(n > 1) {
    
    
            int cur = n / 2; // 比赛次数,也是晋级队伍数量
            ret += cur;	// 计入比赛场次
            n -= cur * 2;  // 轮空队伍数量
            n += cur;  // 晋级队伍 + 轮空队伍 = 剩余队伍数量
        }
        return ret;
    }
};

复杂度分析:

时间复杂度为 O ( l g n ) O(lgn) O(lgn),空间复杂度为 O ( 1 ) O(1) O(1)


题目2:5626. 十-二进制数的最少数目

思路:模拟

求字符串中出现的最大的数字即可

代码:

class Solution {
    
    
public:
    int minPartitions(string n) {
    
    
        int ret = 0;
        for(char c : n) {
    
    
            ret = max(ret, c - '0');
        }
        return ret;
    }
};

复杂度分析:

时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( 1 ) O(1) O(1)


题目3:5627. 石子游戏 VII

思路:动态规划

对于两个选手,希望的都是尽可能扩大两人得分之间的差值,维护二维数组 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示在 [ i , j ] [i, j] [i,j] 区间内删除最左边或者最右边的数后得分的更大差值。如果删除 s t o n e s [ i ] stones[i] stones[i],得分为 [ i + 1 , j ] [i + 1, j] [i+1,j] 区间的石子值总和(可以提前维护前缀和通过 O ( 1 ) O(1) O(1) 得到),然后第二个人能得到的最大差值为 d p [ i + 1 ] [ j ] dp[i + 1][j] dp[i+1][j],同理,如果删除 s t o n e s [ j ] stones[j] stones[j],得分为 [ i , j − 1 ] [i, j - 1] [i,j1] 区间的石子值总和,第二个人能得到的最大差值为 d p [ i ] [ j − 1 ] dp[i][j - 1] dp[i][j1]

由于 Alice 希望提高差值,Bob也希望提高差值,两人希望的差值方向不同,所以更新时需要比较得分与下一个人差值的,也即 d p [ i ] [ j ] = m a x ( s c o r e 1 − d p [ i + 1 ] [ j ] , s c o r e 2 − d p [ i ] [ j − 1 ] ) dp[i][j] = max(score_1 - dp[i + 1][j], score_2 - dp[i][j - 1]) dp[i][j]=max(score1dp[i+1][j],score2dp[i][j1])

由于一个区间的差值 d p [ i ] [ j ] dp[i][j] dp[i][j] 是由更小的区间内的差值得来的,所以遍历更新是要维护区间长度从小到大。

特别地,$ i = j$ 时,说明当前数组只剩下一个元素,此时删除该元素无法得分,所以初始化 d p [ i ] [ i ] = 0 dp[i][i] = 0 dp[i][i]=0

代码:

class Solution {
    
    
public:
    int stoneGameVII(vector<int>& a) {
    
    
        int n = a.size();
        vector<int> v(n + 1, 0);
        for(int i = 1; i <= n; i++) v[i] = v[i - 1] + a[i - 1];
        vector<vector<int>> dp(n, vector<int>(n, 0));
        
        for(int k = 1; k < n; k++) {
    
    
            for(int i = 0; i < n; i++) {
    
    
                int j = i + k;
                if(j == n) break;
                dp[i][j] = max(v[j + 1] - v[i + 1] - dp[i + 1][j],\
                               v[j] - v[i] - dp[i][j - 1]);
            }
        }
        return dp[0][n - 1];
    }
};

复杂度分析:

时间复杂度为 O ( n 2 ) O(n^2) O(n2),相当于遍历了所有子区间,共有 n + n − 1 + . . . + 1 = n ( n + 1 ) 2 n + n - 1 + ... + 1 = \frac{n(n + 1)}{2} n+n1+...+1=2n(n+1) 个子区间

空间复杂度为 O ( n 2 ) O(n^2) O(n2),维护了二维数组


题目4:5245. 堆叠长方体的最大高度

思路:动态规划

如果两个长方体可以拼接,根据题意,长宽高都需要满足同样的大小关系,则不管从什么方向都可以拼接。为了提高拼接后的长度,我们只需要将这三个指标中较长的一个单独提取出来作为高。

因此,我们先对每个长方体进行长宽高排序(将最长的作为高),然后对所有长方体进行排序,再遍历更新最大值即可(类似于最大上升子序列)

代码:

class Solution {
    
    
public:
    int maxHeight(vector<vector<int>>& a) {
    
    
        int n = a.size();
        for (auto &aa : a) sort(aa.begin(), aa.end());
        sort(a.begin(), a.end());
        vector<int> dp(n);
        int ret = 0;
        for(int i = 0; i < n; i++) {
    
    
            for(int j = 0; j < i; j++) {
    
    
                if(a[j][1] <= a[i][1] && a[j][2] <= a[i][2]) {
    
    
                    dp[i] = max(dp[i], dp[j]);
                }
            }
            dp[i] += a[i][2];  // 加上高度
            ret = max(ret, dp[i]);
        }
        return ret;
    }
};

复杂度分析:

时间复杂度为 O ( n 2 ) O(n^2) O(n2),空间复杂度为 O ( n 2 ) O(n^2) O(n2)

猜你喜欢

转载自blog.csdn.net/weixin_42396397/article/details/111097690
今日推荐