Leetcode 第 108 场双周赛 Problem C 将字符串分割为最少的美丽子字符串(动态规划)

这篇具有很好参考价值的文章主要介绍了Leetcode 第 108 场双周赛 Problem C 将字符串分割为最少的美丽子字符串(动态规划)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • Leetcode 第 108 场双周赛 Problem C 将字符串分割为最少的美丽子字符串(动态规划)
  • 题目
    • 给你一个二进制字符串 s ,你需要将字符串分割成一个或者多个 子字符串 ,使每个子字符串都是 美丽 的。
    • 如果一个字符串满足以下条件,我们称它是 美丽 的:
      • 它不包含前导 0 。
      • 它是 5 的幂的 二进制 表示。
    • 请你返回分割后的子字符串的 最少 数目。如果无法将字符串 s 分割成美丽子字符串,请你返回 -1 。
    • 子字符串是一个字符串中一段连续的字符序列。
    • 1 <= s.length <= 15
    • s[i] 要么是 ‘0’ 要么是 ‘1’ 。
  • 解法
    • 动态规划:首先第一位为 0 一定有前导 0,
    • 定义状态(子问题):dp[i] 下标 i 前面结束,最少可以分割成多少美丽子字符串
    • 定义转移方程:当前为 1 前面才可以分割,然后当 [i,j] 以及 [j+1,n+1)均符合要求时 dp[i] = min(dp[j + 1] + 1)
    • 设 m 为 5 次幂的个数,n 为 s.length(n),时间复杂度:O(n ^ 2),空间复杂度:O(n + m)
  • 代码
    /**
     * 动态规划:首先第一位为 0 一定有前导 0,
     * 定义状态(子问题):dp[i] 下标 i 前面结束,最少可以分割成多少美丽子字符串
     * 定义转移方程:当前为 1 前面才可以分割,然后当 [i,j] 以及 [j+1,n+1)均符合要求时 dp[i] = min(dp[j + 1] + 1)
     * 设 m 为 5 次幂的个数,n 为 s.length(n),时间复杂度:O(n ^ 2),空间复杂度:O(n + m)
     */
    private int solution2(String s) {
        // 第一位为 0 一定有前导 0
        if (s.charAt(0) == '0') {
            return -1;
        }

        // 定义状态(子问题),多加一位方便计算
        int[] dp = new int[s.length() + 1];

        // 初始化
        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[s.length()] = 0;

        // 将符合要求的 5 的次幂放入集合
        Set<Integer> beautifulSet = setBeautifulSet();

        // 定义转移方程
        doMinimumBeautifulSubstrings(s, beautifulSet, dp);

        return dp[0] == Integer.MAX_VALUE ? -1 : dp[0];
    }

    /**
     * 将符合要求的 5 的次幂放入集合
     */
    private Set<Integer> setBeautifulSet() {
        Set<Integer> beautifulSet = new HashSet<>();

        int beautifulNum = 1;
        for (int i = 0; i < 7; i++) {
            beautifulSet.add(beautifulNum);
            beautifulNum *= 5;
        }

        return beautifulSet;
    }

    /**
     * 定义转移方程
     */
    private void doMinimumBeautifulSubstrings(String s, Set<Integer> beautifulSet, int[] dp) {
        for (int i = s.length() - 1; i >= 0; i--) {

            // 当前为 1 前面才可以分割
            if (s.charAt(i) == '1') {
                int num = 0;

                // 当 [i,j] 以及 [j+1,n+1)均符合要求时 dp[i] = min(dp[j + 1] + 1)
                for (int j = i; j < s.length(); j++) {
                    // 计算 [i,j)二进制代表的数
                    num = (num << 1) + s.charAt(j) - '0';

                    if (dp[j + 1] != Integer.MAX_VALUE && beautifulSet.contains(num)) {
                        dp[i] = Math.min(dp[i], dp[j + 1] + 1);
                    }
                }
            }
//            System.out.println(i + " : " + dp[i]);
        }
    }

文章来源地址https://www.toymoban.com/news/detail-556622.html

到了这里,关于Leetcode 第 108 场双周赛 Problem C 将字符串分割为最少的美丽子字符串(动态规划)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【力扣周赛】第 113 场双周赛(贪心&异或性质&换根DP)

    https://leetcode.cn/contest/biweekly-contest-113/ https://leetcode.cn/problems/minimum-right-shifts-to-sort-the-array/ 提示: 1 = nums.length = 100 1 = nums[i] = 100 nums 中的整数互不相同。 因为数据范围很小,所以可以从小到大枚举可能的答案。 https://leetcode.cn/problems/minimum-array-length-after-pair-removals/ 提示: 1

    2024年02月07日
    浏览(32)
  • 第 107 场LeetCode双周赛

    A 最大字符串配对数目 显然各字符串对 间匹配的先后顺序不影响最大匹配数目, 可以从后往前遍历数组, 判断前面是否有和当前末尾构成匹配的. B 构造最长的新字符串 记忆化搜索: 定义状态 p a a , b b , a b , l a s t p_{aa,bb,ab,last} p aa , bb , ab , l a s t ​ 为剩余三种字符串分别为aa、

    2024年02月11日
    浏览(40)
  • LeetCode---121双周赛---数位dp

    2996. 大于等于顺序前缀和的最小缺失整数 2997. 使数组异或和等于 K 的最少操作次数 2998. 使 X 和 Y 相等的最少操作次数 2999. 统计强大整数的数目 简单的模拟题,只要按照题目的要求去写代码即可,代码如下 这题考异或的性质---相同为0,相异为1,我们只要关心nums的异或和与

    2024年01月22日
    浏览(48)
  • leetcode 122双周赛 解题思路+代码

    本人水平有限,只做出3道,最后1道放弃。 给你一个长度为 n 的整数数组 nums 。 一个数组的 代价 是它的 第一个 元素。比方说,[1,2,3] 的代价是 1 ,[3,4,1] 的代价是 3 。 你需要将 nums 分成 3 个 连续且没有交集 的子数组。 请你返回这些子数组的 最小 代价 总和 。 示例 1: 输

    2024年02月20日
    浏览(41)
  • 第 122 场 LeetCode 双周赛题解

    A 将数组分成最小总代价的子数组 I 枚举:枚举后两个子数组的起始下标 B 判断一个数组是否可以变为有序 模拟:模拟冒泡排序的过程,若相邻元素大小关系需要交换位置,但其二进制下数位为 1 的数目不同,则返回false,若完成排序返回true C 通过操作使数组长度最小 脑筋急

    2024年01月22日
    浏览(39)
  • LeetCode 双周赛 106(2023/06/10)两道思维题

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 加入知识星球提问。 往期回顾:LeetCode 单周赛第 348 场 · 数位 DP 模版学会了吗? T1. 判断一个数是否迷人(Easy) 标签:计数 T2. 找到最长的半重复子字符串(Medium) 标签:同向双指针 T3. 移动机器人(Medi

    2024年02月08日
    浏览(38)
  • ( 字符串) 205. 同构字符串 ——【Leetcode每日一题】

    难度:简单 给定两个字符串 s 和 t ,判断它们是否是同构的。 如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。 每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个

    2024年02月02日
    浏览(53)
  • LeetCode_字符串_简单_415.字符串相加

    给定两个字符串形式的非负整数 num1 和num2,计算它们的和并同样以字符串形式返回。 你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。 示例 1: 输入:num1 = “11”, num2 = “123” 输出:“134” 示例 2: 输入:num1 = “

    2024年02月01日
    浏览(42)
  • LeetCode 双周赛 103(2023/04/29)区间求和的树状数组经典应用

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问。 大家好,我是小彭。 这场周赛是 LeetCode 双周赛第 103 场,难得在五一假期第一天打周赛的人数也没有少太多。这场比赛前 3 题比较简单,我们把篇幅留给最后一题。 往期周赛回顾:LeetCode 单周赛第

    2024年02月02日
    浏览(61)
  • LeetCode 2788.按分隔符拆分字符串:模拟(字符串处理)

    力扣题目链接:https://leetcode.cn/problems/split-strings-by-separator/ 给你一个字符串数组 words 和一个字符 separator ,请你按 separator 拆分 words 中的每个字符串。 返回一个由拆分后的新字符串组成的字符串数组, 不包括空字符串 。 注意 separator 用于决定拆分发生的位置,但它不包含在

    2024年01月21日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包