[leetcode 周赛 148] 1147 段式回文

2023-11-12

1147 Longest Chunked Palindrome Decomposition 段式回文

描述

段式回文 其实与 一般回文 类似,只不过是最小的单位是 一段字符 而不是 单个字母
举个例子,对于一般回文 "abcba" 是回文,而 "volvo" 不是,但如果我们把 "volvo" 分为 "vo"、"l"、"vo" 三段,则可以认为 “(vo)(l)(vo)” 是段式回文(分为 3 段)。
给你一个字符串 text,在确保它满足段式回文的前提下,请你返回 段 的 最大数量 k。
如果段的最大数量为 k,那么存在满足以下条件的 a_1, a_2, ..., a_k

每个 a_i 都是一个非空字符串;

将这些字符串首位相连的结果 a_1 + a_2 + ... + a_k 和原始字符串 text 相同;
对于所有1 <= i <= k,都有 a_i = a_{k+1 - i}

  • 示例1

    输入:text = "ghiabcdefhelloadamhelloabcdefghi"
    输出:7
    解释:我们可以把字符串拆分成 "(ghi)(abcdef)(hello)(adam)(hello)(abcdef)(ghi)"。

  • 示例2

    输入:text = "merchant"
    输出:1
    解释:我们可以把字符串拆分成 "(merchant)"。

  • 示例3

    输入:text = "antaprezatepzapreanta"
    输出:11
    解释:我们可以把字符串拆分成 "(a)(nt)(a)(pre)(za)(tpe)(za)(pre)(a)(nt)(a)"。

  • 示例4

    输入:text = "aaa"
    输出:3
    解释:我们可以把字符串拆分成 "(a)(a)(a)"。

  • 提示

    text 仅由小写英文字符组成。
    1 <= text.length <= 1000

思路

  • 两边字段定位 [i, j) --> [n-j-1, n-i-1)
    1640888-20190806224100154-594542842.png

可以有两种方式实现:

  1. 暴力遍历
  2. String.substring(beginIndex, endIndex) 注意字段范围[beginIndex, endIndex)
  • 进入下一轮判断
    有两种方式:递归/迭代

递归: (0, n-1) --> (0, s)==(e,n-1) (s,e) -->

开始时, 起始为0, 终止为n-1
遍历0~n-1, 找到(0, s)==(e,n-1)
此时设起始为s, 终止为e 开始下一轮

迭代: i -> n/2 --> (j, i) -->

开始遍历 1~n/2 枚举为终止位置i
选取j=0 作为开始位置
找到(j, i)==(n-i-1, n-j-1)
设j=i 作为开始位置 开始下一循环

代码实现

贪心算法

每次两端有相同的字段就将其分词, 并投入到下一轮递归中, 直至字符串为空或者无法进行分词为止
1640888-20190806224112532-309014606.png

class Solution {
    public int longestDecomposition(String text) {
        if (null == text) return -1;
        
        int n = text.length();
        // 将字符串分成 [0,i) ~ [n-i, n)
        // 如果上面相等 表示有2份回文字段
        // 并将剩余字段投入下一轮迭代 [i, n-i)
        // i 其实表示的是比较字段的长度
        for (int i = 1; i <= n/2; i++) {
            if (text.substring(0, i).equals(text.substring(n-i, n))) {
                return 2 + longestDecomposition(text.substring(i, n-i));
            }
        }
        
        // 当最终剩余字段大于零 则其单独成一段 +1
        return n == 0 ? 0 : 1;
    }
}

动态规划(使用二维数组)

1640888-20190806224125612-613473631.png

class Solution {
    int[][] dp;
    String text;
    
    public int longestDecomposition(String text) {
        int n = text.length();
        dp = new int[n][n];
        
        // 初始化为-1 用以表示该位置是否被处理
        for (int i = 0; i < n; i++) Arrays.fill(dp[i], -1);
        this.text = text;
        
        // 求整个字符串的回文字段k
        return helper(0, n-1);
    }
    
    /**
     * 求回文字段数 text的子串
     * @param s 起始位置
     * @param e 终止位置
     * @return 该字段的回文字段数
     **/
    int helper(int s, int e) {
        // 非法字段 起始位置大于终止位置
        if (s > e) return 0;
        // 特殊情况 刚好只剩下一个字符
        if (s == e) return dp[s][e] = 1;
        // 不为-1 则表示以及处理过 直接拿来用就可以
        if (dp[s][e] != -1) return dp[s][e];
        
        // 字符串本身算一回文字段
        int res = 1;
        // 枚举长度 1 ~ (e-s+1)/2 从s开始的子串
        for (int l = 1; l <= (e-s+1)/2; l++) {
            String st = text.substring(s, s+l);
            String ed = text.substring(e-l+1, e+1);
            // 如果两子串相等 表示找到回文字段 +2
            if (st.equals(ed)) {
                int tmp = helper(s+l, e-l);
                // 更新结果值
                res = tmp+2;
            }
        }
        
        return dp[s][e] = res;
    }
}

动态规划(使用一维数组)

1640888-20190806224134115-278403160.png

class Solution {
    // 存储表示0~i 出现的回文字段
    int dp[] = new int[1050];
    
    public int longestDecomposition(String text) {
        int n = text.length(), ans = 1;
        char[] chs = text.toCharArray();
        
        // dp数组初始化
        Arrays.fill(dp, -1);
        // 肯定是有从0开始的回文字段
        dp[0] = 0;
        
        // 表示最新的子串开始位置
        int left = 0;
        // i 表示终止位置 (j, i)
        for (int i = 1; i <= n/2; i++) {
            for (int j = left; j < i; j++) {
                // 可不可以作为起始点
                if (dp[j] == -1) continue;
                // [j, i-1]是否可以作为回文字段
                if (!check(chs, j, i, n)) continue;
                // 如果可以作为回文字段
                // [0,i) 有多少回文字段
                dp[i] = dp[j]+1;
                // 更新最新子串开始位置
                left = i;
            }
        }

        // 如果最终处理字段的位置 并没有遍历完字符串(n/2) 表示还有剩余1字段可以作为回文字段
        return Math.max(dp[left]*2 + (left*2<n?1:0), ans);
    }
    
    /**
     * 检查[j,i-1]段前后是否相等
     * 暴力遍历
     **/
    boolean check(char[] chs, int j, int i, int n) {
        // j ~ i-1 --> n-i ~ n-j-1
        for (int ii = j; ii < i; ii++) {
            if (chs[ii] != chs[n-i-j+ii]) return false;
        }
        return true;
    }
}

转载于:https://www.cnblogs.com/slowbirdoflsh/p/11312365.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[leetcode 周赛 148] 1147 段式回文 的相关文章

  • 五大常用经典算法

    五大常用算法之一 分治算法 一 基本概念 在计算机科学中 分治法是一种很重要的算法 字面上的解释是 分而治之 就是把一个复杂的问题分成两个或更多的相同或相似的子问题 再把子问题分成更小的子问题 直到最后子问题可以简单的直接求解 原问题的解即
  • 以OpenGL/ES视角介绍gfx-hal(Vulkan) Shader/Program接口使用

    文档列表见 Rust 移动端跨平台复杂图形渲染项目开发系列总结 目录 背景 The right way to tackle this in Vulkan is to use resource descriptors A descriptor
  • 数据结构中常见的树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)

    原文 http blog csdn net sup heaven article details 39313731 数据结构中常见的树 BST二叉搜索树 AVL平衡二叉树 RBT红黑树 B 树 B 树 B 树 转载 2014年09月16日
  • Sort List

    Sort a linked list in O n log n time using constant space complexity 题目要求用 O n log n 的时间复杂度和常数的空间复杂度来进行链表排序 O nlogn 的排序算
  • (笔试前准备)字符串匹配算法总结

    我想说一句 我日 我讨厌KMP KMP虽然经典 但是理解起来极其复杂 好不容易理解好了 便起码来巨麻烦 老子就是今天图书馆在写了几个小时才勉强写了一个有bug的 效率不高的KMP 特别是计算next数组的部分 其实 比KMP算法速度快的算法
  • Hash table and application in java

    查找的效率取决于在查找是比较的次数 次数越少效率越高 反之越低 最理想的情况是无需比较 一次存取便能找到所查找的记录 根据对应关系f找到给定值K的像f K hash function 应运而生 由此思想建的表称为hash table 集合h
  • PCL—低层次视觉—点云分割(RanSaC)

    点云分割 点云分割可谓点云处理的精髓 也是三维图像相对二维图像最大优势的体现 不过多插一句 自Niloy J Mitra教授的Global contrast based salient region detection出现 最优分割到底鹿死
  • findBug 错误修改指南

    FindBugs错误修改指南 1 EC UNRELATED TYPES Bug Call to equals comparing different types Pattern id EC UNRELATED TYPES type EC c
  • 用 Java 实现的八种常用排序算法

    八种排序算法可以按照如图分类 前置知识 1 算法稳定性 在一个序列中 能保证两个相等的数 经过排序之后 其在序列的前后位置顺序不变 A1 A2 排序前 A1 在 A2 前面 排序后 A1 还在 A2 前面 2 时间复杂度 时间复杂度是用于衡
  • 亚利桑那州立大学周纵苇:研习 U-Net ——现有的分割网络创新

    雷锋网AI研习社按 经典的 Encoder Decoder 结构在目标分割问题中展现出了举足轻重的作用 然而这样一个相对固定的框架使得模型在感受野大小和边界分割精度两方面很难达到兼顾 本次公开课 讲者以 U Net 为案例分析 总结现有的分
  • 如何根据链表节点数据大小对链表节点进行排序

    对链表排序有两种方法 1 比较了两个节点的大小后 对指针进行改变 从而交换节点的顺序 2 比较了两个节点的大小后 只交换数据域 而不改变指针 从而交换节点的顺序 第二种办法比较简单 本文主要对第二种方法进行讲解 链表节点排序算法 采用 冒泡
  • 如何防止过拟合和欠拟合

    过拟合和欠拟合是模型训练过程中经常出现的问题 两种情况正好相反 现将两者的定义及如何防止进行简要总结 1 过拟合 1 1 定义 是指模型对于训练数据拟合呈现过当的情况 反映到评估指标上就是模型在训练集上的表现很好 但是在测试集上的表现较差
  • CRC校验(二)

    CRC校验 二 参考 https blog csdn net liyuanbhu article details 7882789 https www cnblogs com esestt archive 2007 08 09 848856
  • 数据结构与算法-列表(双向链表)设计及其排序算法

    0 概述 本文主要涵盖列表 双向链表 的设计及其排序算法的总结 列表是一种典型的动态存储结构 其中的数据 分散为一系列称作节点 node 的单位 节点之间通过指针相互索引和访问 为了引入新节点或删除原有节点 只需在局部调整少量相关节点之间的
  • Linux下进程退出的几种形式

    进程退出 Linux 下进程的退出分为正常退出和异常退出两种 1 正常退出 a 在main 函数中执行return b 调用exit 函数 c 调用 exit 函数 2 异常退出 a 调用about函数 b 进程收到某个信号 而该信号使程序
  • 区块链中的哈希算法

    区块链中的密码学 密码学在区块链中的应用主要有两个 哈希算法与非对称加密算法 这次主要对哈希算法进行详细的说明 哈希算法 哈希算法的特点有 1 输入可以为任意大小的字符串 2 产生固定大小的输出 3 可以在合理的时间内算出输出值 若要满足密
  • 基数排序代码实现

    详情请看排序总结 传送门 https blog csdn net m0 52711790 article details 121914543 基数排序的知识点我就不贴出来 相信都能搜到对应概念解释 下面就直接上代码 代码解释其实也很清晰了
  • 【数据结构】双链表的定义和操作

    目录 1 双链表的定义 2 双链表的创建和初始化 3 双链表的插入节点操作 4 双链表的删除节点操作 5 双链表的查找节点操作 6 双链表的更新节点操作 7 完整代码 嗨 我是 Filotimo 很高兴与大家相识 希望我的博客能对你有所帮助
  • 浅谈归并排序:合并 K 个升序链表的归并解法

    在面试中遇到了这道题 如何实现多个升序链表的合并 这是 LeetCode 上的一道原题 题目具体如下 用归并实现合并 K 个升序链表 LeetCode 23 合并K个升序链表 给你一个链表数组 每个链表都已经按升序排列 请你将所有链表合并到
  • 最大流-Dinic算法,原理详解,四大优化,详细代码

    文章目录 零 前言 一 概念回顾 可略过 1 1流网络 1 2流 1 3最大流 1 4残留网络 1 5增广路

随机推荐

  • 分布式三高商城系统前言

    商城系统前言 前言 本商城致力于为中大型企业打造一个功能完整 易于维护的微服务B2B2C电商商城系统 采用主流的微服务技术实现 完全从零开始带领大家完成一个商城系统 包括基础的项目环境搭建 后端业务代码编写 前端页面等 微服务设计 mall
  • 多租户SaaS管理系统框架设计:多租户,多组织,用户区别

    数商云 已认证的官方帐号 转载自 多租户SaaS管理系统框架设计 多租户 多组织 用户区别 知乎 今天谈下云平台下的多租户架构 不论是在公有云还是私有云平台 是设计一个面向最终组织或用户的SaaS应用还是面向业务系统的PaaS平台 多租户都
  • 【物流配送的车辆路径问题】

    物流配送的车辆路径问题 提示 这里可以添加系列文章的所有文章的目录 目录需要自己手动添加 Two echelon capacitated vehicle routing problem with grouping constraints a
  • Human Gene Functions

    http acm hdu edu cn showproblem php pid 1080 Problem Description It is well known that a human gene can be considered as
  • leetcode刷题(10.22总结)

    1 丢失的数字 题目描述 https leetcode cn problems missing number class Solution def missingNumber self nums List int gt int n len
  • 基于SSM+MySQL在线书城项目

    目录 1 项目简介 2 项目说明 3 项目功能 4 项目展示 5 项目获取 1 项目简介 随着互联网发展 网上商城越来越活跃 线下购物方式逐渐弱化 在线购物越来越获得公众的欢迎 在线书城项目是一款B2C的线上购书系统 用户可以在本网站上购买
  • IDEA导入Web项目的三种方式

    文章目录 前言 一 第一种方式 二 第二种方式 三 第三种方式 前言 无论那种方式 它们都有相同的前提 那就是首先将你想要导入的Web项目放置在你想要导入的工程目录下 例如 举例子 笔者要将一个名为mavenWeb1的Web项目 笔者自己的
  • idm 服务器响应显示您没有权限下载此文件_玩转IDM,你不知道的IDM巧妙使用方法...

    在此前分享过的一系列百度网盘加速下载文章中 IDM Internet Download Manager 是不可或缺的一个环节 IDM 除了可以用来加速下载百度网盘资源外 其本身也是一款非常强大的下载器 它高速 精简 高效 把 一个程序做好一
  • 远程桌面控制台,有标签页可以管理多个远程桌面

    Server 2003系统自带远程桌面控制台 有标签页可以管理多个远程桌面 在windows的其他系统如果要实现可以参照以下操作 1 将server2003系统C WINDOWS system32目录下的mstsmhst dll mstsm
  • Android之 WebView的使用

    一 简介 1 1 WebView是用来展示网页的控件 底层是google的WebKit的引擎 比起苹果的WebView webkit一些不足地方 不能支持word等文件的预览 纯标签加载 并不支持所有标签的加载 不支持文件的下载 图片的放大
  • Elasticsearch 索引增删改

    添加小编微信 372787553 进入程序员技术交流群 本文已被 ElasticSearch从入门到入魔 收录 Elasticsearch 增删改 在前面我们已经安装好了elasticsearch 已经kibana 如果您还没有安装可以参考
  • 区块链倪老师:《区块链思维》第二章——“二维思维”的使用方法

    上回在 区块链思维 第一章中 我们已经从 一维思维 进阶到了 二维思维 今天我们就来讲讲如何使用 二维思维 二维思维 也叫结构化思维 顾名思义是将知识进行结构化的一种思维方式 同样 在区块链系统中 不同的部分分别构成了不同的结构 一般说来
  • 我的Android进阶之旅------>经典的大客推荐(排名不分先后)!!

    今天看到一篇文章 收藏了很多大牛的博客 在这里分享一下 转载于 http blog csdn net wujxiaoz article details 8237096 Android中文Wiki AndroidStudio NDK开发 移动
  • 思维导图系列——数据库

    思维导图系列 数据库 思维导图为博主期末复习亲自整理而成的 知识点覆盖全 可直接看思维导图复习 包含注解 图示等 觉得对你有帮助 不妨一键三连哦 链接见文末 参考书目 数据库系统概论 第5版 王珊 系列文章直达 思维导图系列 操作系统 思维
  • Qt信号与槽机制的本质

    引入 对象与对象之间的通信有多个方式 如果我们要提供一种对象之间的通信机制 这种机制 要能够给两个不同对象中的函数建立映射关系 前者被调用时后者也能被自动调用 再深入一些 两个对象如果都互相不知道对方的存在 仍然可以建立联系 甚至一对一的映
  • 人物故事

    李飞飞 导语 今年9月11日 谷歌云AI部门负责人李飞飞宣布即将离职 回到斯坦福大学任教 外媒 连线 杂志日前刊文 讲述了李飞飞离职背后的故事 以下为文章全文 去年六月有段时间 凌晨一点左右 李飞飞穿着睡衣 坐在华盛顿特区酒店房间里 练习几
  • web页面攻击分为几类?可以提供几种解决方案吗?

    WEB基本攻击大致可以分为三大类 资源枚举 参数操纵 和 其它攻击 资源枚举 遍历站点所有可访问的目录 然后把一些常见的备胎文件名 比如 sql bak index 副本 html 一个个都枚举一下 如果运气好枚举到了就直接下载 参数操纵
  • 嵌入式linux通过systemd自启动一个c代码

    上一篇博文说了嵌入式linux通过systemd自启动一个python代码 这次把python代码改为c代码 再试试 主要有两个文件 etc systemd system autostart service 用于启动 home roor a
  • 【Error】Call requires API level 3 (current min is 1)解决办法

    今天从网上下载了一个程序 本来好好的 后来不知道怎么弄的就不好使了 解决办法 在工程上右键 gt Android Tools gt Clear Lint Markers
  • [leetcode 周赛 148] 1147 段式回文

    目录 1147 Longest Chunked Palindrome Decomposition 段式回文 描述 思路 代码实现 1147 Longest Chunked Palindrome Decomposition 段式回文 描述 段