LeetCode 第 388 场周赛个人题解

目录

[100233. 重新分装苹果](#100233. 重新分装苹果)

原题链接

思路分析

AC代码

[100247. 幸福值最大化的选择方案](#100247. 幸福值最大化的选择方案)

原题链接

思路分析

AC代码

[100251. 数组中的最短非公共子字符串](#100251. 数组中的最短非公共子字符串)

原题链接

思路分析

AC代码

[100216. K 个不相交子数组的最大能量值](#100216. K 个不相交子数组的最大能量值)

原题链接

思路分析

AC代码


100233. 重新分装苹果

原题链接

100233. 重新分装苹果

思路分析

直接模拟

降序排序capacity,倒序累加,当大于苹果总重量的时候我们就返回

时间复杂度:O(nlgon)

AC代码

cpp 复制代码
class Solution {
public:
    int minimumBoxes(vector<int>& apple, vector<int>& capacity) {
        int s = accumulate(apple.begin(), apple.end(), 0);
        int n = capacity.size();
        sort(capacity.begin(), capacity.end(), [](int x, int y){return y < x;});
        for(int i = 0, t = 0; i < n; i++) {
            t += capacity[i];
            if(t >= s) return i + 1;
        }
        return n;
    }
};

100247. 幸福值最大化的选择方案

 

原题链接

  100247. 幸福值最大化的选择方案

思路分析

  贪心

优先分配幸福值大的孩子,然后直接模拟

时间复杂度:O(nlgon)

AC代码

cpp 复制代码
class Solution {
public:
    long long maximumHappinessSum(vector<int>& a, long long k) {
        long long ret = 0;
        sort(a.begin(), a.end(), [](int x, int y){return x > y;});
        for(int i = 0, t = 0; i < k; i++, t++){
            if(a[i] > t) ret += a[i] - t;
        }
        return ret;
    }
};

100251. 数组中的最短非公共子字符串

原题链接

100251. 数组中的最短非公共子字符串

 

思路分析

其实直接暴力就行了

用哈希表或者字典树存储所有字符串的所有子串,然后遍历每个字符串的子串找到不在哈希表或者字典树中的子串中最短并且字典序最小的那个

想着复习下字典树就敲了下字典树

时间复杂度分析:

子串长度有k种,起点有k个,那么存储一个长度为k的字符串的所有子串就是O(k^3)

然后枚举n个字符串的所有字串并判断就是O(n*k^3)

因为k最大也就20,n最大100,因而整体也就1e6左右

故**时间复杂度O(n*k^3)**是可以的

AC代码

cpp 复制代码
struct node{
    unordered_map<char,node*>ch;
    unordered_set<int> words;
};
class Solution {
public:
    vector<string> shortestSubstrings(vector<string>& arr) {
        node* rt = new node, *cur;
        vector<string> ret;
        for(int k = 0, sz = arr.size(); k < sz; k++)
            for(int i = 0, n = arr[k].size(); i < n; i++){
                cur = rt;
                for(int j = i; j < n; j++){
                    if(!cur->ch.count(arr[k][j])) cur->ch[arr[k][j]] = new node;
                    cur = cur->ch[arr[k][j]], cur->words.insert(k);
                }
                    
            }

        for(int k = 0, sz = arr.size(); k < sz; k++){
            string tmp;
            for(int i = 0, j, n = arr[k].size(); i < n; i++){
                cur = rt;
                for(j = i; j < n; j++){
                    cur = cur->ch[arr[k][j]];
                    if(cur->words.size() == 1){
                        if(tmp.empty() || j - i + 1 < tmp.size() || (j - i + 1 == tmp.size() && arr[k].substr(i, j - i + 1) < tmp)) tmp = arr[k].substr(i, j - i + 1);
                        break;
                    }
                }
            }
            ret.emplace_back(tmp);
        }
        return ret;
    }
};

100216. K 个不相交子数组的最大能量值

原题链接

100216. K 个不相交子数组的最大能量值

思路分析

  考虑题目说n*k <= 1e6,所以想到用dp

定义状态

fij0为前i个元素拆出j个子数组且第i个元素在第j个子数组中的最大能量和

fij1为前i个元素拆出j个子数组且第i个元素不在第j个子数组中的最大能量和

那么有转移方程

fij1 = max(fi - 1j0, fi - 1j1);即不选第i个数,那么直接由上一行转移

选第i个数并且单独成第j组,那么前i-1个数要拆出j-1组,第i-1个数在不在第j-1组取大的那个

if(j)

fij0 = max(fij0, max(fi - 1j - 11, fi - 1j - 10) + 1LL * (j & 1 ? 1 : -1) * (k - j + 1) * numsi - 1);
选第i个数并且加入第j组

fij0 = max(fij0, fi - 1j0 + 1LL * (j & 1 ? 1 : -1) * (k - j + 1) * numsi - 1);

时间复杂度O(nk)

AC代码

cpp 复制代码
class Solution {
public:
    long long maximumStrength(vector<int>& nums, int k) {
        int n = nums.size();
        vector<vector<vector<long long>>> f(n + 1, vector<vector<long long>>(k + 1, vector<long long>(2, -1e18)));
        f[0][0][1] = 0;
        
        for(int i = 1; i <= n; i++){
            for(int j = 0; j <= k; j++){
                //不选
                f[i][j][1] = max(f[i - 1][j][0], f[i - 1][j][1]);
                //选
                //单独成组
                if(j)
                    f[i][j][0] = max(f[i][j][0], max(f[i - 1][j - 1][1], f[i - 1][j - 1][0]) + 1LL * (j & 1 ? 1 : -1) * (k - j + 1) * nums[i - 1]);
                //加到前面
                f[i][j][0] = max(f[i][j][0], f[i - 1][j][0] + 1LL * (j & 1 ? 1 : -1) * (k - j + 1) * nums[i - 1]);
            }
        }
        
        return max(f[n][k][0], f[n][k][1]);
    }
};
相关推荐
孙启超7 小时前
【AI应用开发】Agent 无限 loop(反复调用同一个工具)如何规避?
人工智能·python·算法·llm·agent·loop·ai应用开发
小月土星8 小时前
LeetCode 142. 环形链表 II 超详细题解(快慢指针原理+逐行代码拆解)
算法
dok128 小时前
Johannes 《Linux内核模块与设备驱动开发:编写Linux驱动程序》 (11)kmalloc 动态内存分配和struct file中的私有数据
linux·驱动开发·算法
hansang_IR8 小时前
【题解】[COCI 2024/2025 #2] 流明 / Blistavost
c++·算法·动态规划·dp
不正经学生8 小时前
C语言指针进阶:const 和野指针——给指针加锁,向野指针宣战
c语言·开发语言·c++·算法·c#
程序喵大人8 小时前
【C++进阶】STL算法与函数对象 - 01 让算法去处理一段迭代器范围
开发语言·c++·算法·函数对象
Keven_118 小时前
算法札记:二叉树前序、中序、后序遍历及对应序列重要性质
数据结构·算法·深度优先
Delite8028 小时前
微库仑氧化法硫氯检测:油品分析中测量误差的控制要点
算法
如此这般英俊8 小时前
手搓Claude Code-第十章 system_prompt
数据结构·人工智能·python·语言模型·自然语言处理·prompt
宵时待雨8 小时前
优选算法专题12:队列
算法·leetcode·职场和发展