• LeetCode 单周赛298,前三题


    2309. 兼具大小写的最好英文字母

    给你一个由英文字母组成的字符串 s ,请你找出并返回 s 中的 最好 英文字母。返回的字母必须为大写形式。如果不存在满足条件的字母,则返回一个空字符串。

    最好 英文字母的大写和小写形式必须 都 在 s 中出现。

    英文字母 b 比另一个英文字母 a 更好 的前提是:英文字母表中,b 在 a 之 后 出现。

    示例 1:

    输入:s = “lEeTcOdE”
    输出:“E”
    解释:
    字母 ‘E’ 是唯一一个大写和小写形式都出现的字母。

    示例 2:

    输入:s = “arRAzFif”
    输出:“R”
    解释:
    字母 ‘R’ 是大写和小写形式都出现的最好英文字母。
    注意 ‘A’ 和 ‘F’ 的大写和小写形式也都出现了,但是 ‘R’ 比 ‘F’ 和 ‘A’ 更好。

    示例 3:

    输入:s = “AbCdEfGhIjK”
    输出:“”
    解释:
    不存在大写和小写形式都出现的字母。

    提示:

    1 <= s.length <= 1000
    s 由小写和大写英文字母组成

    思路

    遍历一遍字符串,只要是字母就标记,之后遍历标记数组,从后往前判断,大小写都有的,第一个符合的也是最大的

    代码

    class Solution {
    public:
        int t[100];
        string greatestLetter(string s) {
            string res = "";
            for (int i = 0; i < s.size(); i++) {
                t[s[i] - 'A'] = 1;
            }
            for (int i = 0; i < 26; i++) {
                if (t[i] == 1 && t[i + 32] == 1) {
                    res = i + 'A';
                }
            }
            
            return res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2310. 个位数字为 K 的整数之和

    给你两个整数 num 和 k ,考虑具有以下属性的正整数多重集:

    每个整数个位数字都是 k 。
    所有整数之和是 num 。
    返回该多重集的最小大小,如果不存在这样的多重集,返回 -1 。

    注意:

    多重集与集合类似,但多重集可以包含多个同一整数,空多重集的和为 0 。
    个位数字 是数字最右边的数位。

    示例 1:

    输入:num = 58, k = 9
    输出:2
    解释:
    多重集 [9,49] 满足题目条件,和为 58 且每个整数的个位数字是 9 。
    另一个满足条件的多重集是 [19,39] 。
    可以证明 2 是满足题目条件的多重集的最小长度。

    示例 2:

    输入:num = 37, k = 2
    输出:-1
    解释:个位数字为 2 的整数无法相加得到 37 。

    示例 3:

    输入:num = 0, k = 7
    输出:0
    解释:空多重集的和为 0 。

    提示:

    0 <= num <= 3000
    0 <= k <= 9

    贪心

    拆解,nk + 10t == num

    (num - nk) % 10 == 0

    class Solution {
    public:
        int minimumNumbers(int num, int k) {
            if (num == 0) return 0;
            // 拆解,nk + 10t == num
            // (num - nk) % 10 == 0
    
            for (int i = 1; i <= num && num - k * i >= 0; i++) { 
                if ((num - k * i) % 10 == 0) {
                    return i; // 因为是从小到大模拟的,第一个遇到的合适的条件就是最小值
                }
            }
    
            return -1;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    动态规划1

    当num == 0 时,返回0,如果k是偶数,但是num是奇数,直接返回-1,不可能
    先挑选出来个位是k的数,组成一个数组,作为背包,然后一维滚动数组,动态规划
    外层遍历物品,内层遍历背包容量
    初始化,dp[0] = 0,因为num是0的时候,由0个数字组成,要取组成num的数的个数的最小值,所以数组初始化为无穷大
    dp[j] = min(dp[j - i] + 1, dp[j]),要么就取j-i的数量 + 1,要么就取 dp[j]

    class Solution {
    public:
        int bg[3010];
        int dp[3010];
        int minimumNumbers(int num, int k) {
            if (num == 0) return 0;
            if (num % 2 == 1 && k % 2 == 0) return -1;
            int cnt = 0;
            for (int i = 1; i <= num; i++) {
                if (i % 10 == k) bg[cnt++] = i;
            }
            for (int i = 1; i <= num; i++) dp[i] = 99999;
            dp[0] = 0;
            for (int i = 0; i < cnt; i++) {
                for (int j = bg[i]; j <= num; j++) {
                    dp[j] = min(dp[j - bg[i]] + 1, dp[j]);
                }
            }
            if (dp[num] == 99999) return -1;
            return dp[num];
            
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    动态规划2

    class Solution {
        int dp[3001];
    public:
        int minimumNumbers(int num, int k) {
            memset(dp, 127, sizeof(dp)); // 求最小,初始无穷大
    
            dp[0] = 0;
            for (int i = 0; i <= num; i++) {
                for (int j = i; j <= num; j++) {
                    if (i % 10 == k)
                        dp[j] = min(dp[j - i] + 1, dp[j]);
                }
            }
            if (dp[num] > 1 << 30) return -1;
            return dp[num];
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2311. 小于等于 K 的最长二进制子序列

    给你一个二进制字符串 s 和一个正整数 k 。

    请你返回 s 的 最长 子序列,且该子序列对应的 二进制 数字小于等于 k 。

    注意:

    子序列可以有 前导 0 。
    空字符串视为 0 。
    子序列 是指从一个字符串中删除零个或者多个字符后,不改变顺序得到的剩余字符序列。

    示例 1:

    输入:s = “1001010”, k = 5
    输出:5
    解释:s 中小于等于 5 的最长子序列是 “00010” ,对应的十进制数字是 2 。
    注意 “00100” 和 “00101” 也是可行的最长子序列,十进制分别对应 4 和 5 。
    最长子序列的长度为 5 ,所以返回 5 。

    示例 2:

    输入:s = “00101001”, k = 1
    输出:6
    解释:“000001” 是 s 中小于等于 1 的最长子序列,对应的十进制数字是 1 。
    最长子序列的长度为 6 ,所以返回 6 。

    提示:

    1 <= s.length <= 1000
    s[i] 要么是 ‘0’ ,要么是 ‘1’ 。
    1 <= k <= 109

    贪心?

    设置一个bool数组初始化为 false
    因为可以有前导0,所以先把所有的零都选上,ans记录一下现在的个数
    然后,因为1在右边加的少,在左边加的太多了,所以从右往左加,看看这个1加上之后会不会超

    class Solution {
        bool b[1001];
    public:
        bool check(string &s, int k) {
            int n = s.size(), x = 0;
            for (int i = 1; i <= n; i++) {
                if (b[i])
                    x = x * 2 + s[i - 1] - '0';
                if (x > k)
                    return false;
            }
            return true;
        }
        int longestSubsequence(string s, int k) {
            memset(b, false, sizeof(b));
            int n = s.size();
            int ans = 0; // 记录数字的个数
            
            for (int i = 1; i <= n; i++) { // 首先,加上所有的 0 
                if (s[i - 1] == '0')
                    ++ans, b[i] = true; // 记录当前数字的个数,并且把选中的数字改成 true 
            }
            
            for (int i = n; i > 0; i--)
                if (!b[i]) {    // 从后往前遍历,将刚才没有加进去的 1 
                    b[i] = true;    // 先变成true,方便下面计算
                    if (!check(s, k)) // 如果超了,就去掉
                        b[i] = false;
                    else    // 没有超就++
                        ++ans;
                }
            
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
  • 相关阅读:
    校友录系统
    计算机毕业设计 基于HTML语言的环保网站的设计与实现 Java实战项目 附源码+文档+视频讲解
    浅理解java中的泛型
    安卓逆向-马蜂窝zzzghostsigh算法还原--魔改的SHA-1
    树状数组。 数组修改某个元素的数值/求出前n个元素的和,需要在一百毫秒处理上百万个数字
    BigDecimal不会丢失精度的浮点数
    Java设计模式-工厂模式(FactoryPattern)
    fastjson 1.2.24 rce漏洞复现
    软件生命周期过程
    玩转Mybatis高级特性:让你的数据操作更上一层楼
  • 原文地址:https://blog.csdn.net/Changersh/article/details/125446331