首页 > 编程语言 >算法 -- 分割两个字符串得到回文串

算法 -- 分割两个字符串得到回文串

时间:2023-03-18 18:11:07浏览次数:37  
标签:String -- 算法 bsuffix 字符串 bprefix aprefix 回文

  1. 分割两个字符串得到回文串
    提示
    中等
    114
    相关企业
    给你两个字符串 a 和 b ,它们长度相同。请你选择一个下标,将两个字符串都在 相同的下标 分割开。由 a 可以得到两个字符串: aprefix 和 asuffix ,满足 a = aprefix + asuffix ,同理,由 b 可以得到两个字符串 bprefix 和 bsuffix ,满足 b = bprefix + bsuffix 。请你判断 aprefix + bsuffix 或者 bprefix + asuffix 能否构成回文串。

当你将一个字符串 s 分割成 sprefix 和 ssuffix 时, ssuffix 或者 sprefix 可以为空。比方说, s = "abc" 那么 "" + "abc" , "a" + "bc" , "ab" + "c" 和 "abc" + "" 都是合法分割。

如果 能构成回文字符串 ,那么请返回 true,否则返回 false 。

注意, x + y 表示连接字符串 x 和 y 。

示例 1:

输入:a = "x", b = "y"
输出:true
解释:如果 a 或者 b 是回文串,那么答案一定为 true ,因为你可以如下分割:
aprefix = "", asuffix = "x"
bprefix = "", bsuffix = "y"
那么 aprefix + bsuffix = "" + "y" = "y" 是回文串。
示例 2:

输入:a = "abdef", b = "fecab"
输出:true
示例 3:

输入:a = "ulacfd", b = "jizalu"
输出:true
解释:在下标为 3 处分割:
aprefix = "ula", asuffix = "cfd"
bprefix = "jiz", bsuffix = "alu"
那么 aprefix + bsuffix = "ula" + "alu" = "ulaalu" 是回文串。

提示:

1 <= a.length, b.length <= 105
a.length == b.length
a 和 b 都只包含小写英文字母

解法:

  1. 刚开始想的暴力,就是抽取一个判断回文的方法,然后循环拆组字符串判断
class Solution {
    public boolean checkPalindromeFormation(String a, String b) {
        int n = a.length();
        if(checkPalindrome(a)||checkPalindrome(b)){
            return true;
        }
        String apre,asuf,bpre,bsuf;
        for(int i =1;i<n;i++){
            apre = a.substring(0,i);
            asuf = a.substring(i);
            bpre = b.substring(0,i);
            bsuf = b.substring(i);
            apre += bsuf;
            bpre += asuf;
            if(checkPalindrome(apre) || checkPalindrome(bpre)){
                return true;
            }
        }
        return false;

    }
    private boolean checkPalindrome(String a){
        int n = a.length();
        if(n == 0)return true;
        String a1 = a.substring(0,n/2);
        String a2;
        if(n%2 == 1){
            a2 = a.substring(n/2+1);
        }else{
            a2 = a.substring(n/2);
        }
        StringBuilder s2 = new StringBuilder(a2);
        a2 = s2.reverse().toString();
        if(a1.equals(a2)){
            return true;
        }else{
            return false;
        }
    }
}

不出所料,超时了 -- (这用例真的sm)

最后执行的输入
添加到测试用例
a =
"dtcwxqkdksglobkkcvcxwisgjfecszsfgcamrmxnplgffgdhpigywnlyexpgqgbdgjssnxrkntivitjpzfzvlqxvgsfcsinbvanrbrrnprtjgsivyqgfgjskdjkhwiznmlmatelxttlasfxtktrfjizdbzpeqdyznnniykjqctcyopnfcyrvvnyazjaymogzlrlzuszsfnbvxxewogoesiupqdtiwfbwcvtogwltbrtxhvkaiejgcrxwlaumcgiiumneodokfeakijoqmijuzywnotfxngroqphxtpdmufjjsmtoihfiamtzvabmtufexmxlejjkcjxubelgqprhxhlizzwqflmjfhoxvsoypahjcowfyguraqivzzvmzvwbtfcgfkbgxxohydsjrfbdshdbhlykdtvhfzjxkwitibuhepyubxzurqrbpmaplpibgwnbhqemtflxlsxjukhokynzktkxfseexcejszdsgmyodkgpovgrafqrtgvwhjxgcbzwofhyfsijwgdwdwjkctwpyczbmqdfsdihrsxadltmvqurxqokmtfwhwljopzqfmijpiqfbqcglsldmbdueifbdebxgkvvcfifrkayvmrwlensmiazffqhohchousnzyehngxzrpzkvrmwiygrqdbrtntpwhicnzdictmwhdzudbantyngydvdwtstpanrdwnsuwshcigmmyoltccxyfwuimyzfyoflrqdermdjktt...
result.viewAll 
b =
"oulkdvaesuyzjxtgtttovvehkprxbblksnoofxwylfoljmkoklcztiqtvqshfvzmqcqmusloxjdtayytkyqnjgszjdjrildgsicnrcyynbqezumearjzgblnquhmdxlxyjgjikjznftedqfsubncyzmglkyetstexsaqczxxbohlokjvzbrbkylqwvwmfbmcuqnatqpartphwvvrqjadtbfoduwkgnzanrciejzgiplfxhoyuhjrtpumvnvkpuzzsxdivcpaicbgmmdbryymheczcrfbuneaajpngbobibvktlnoelsumpdtmyjenpadpsgawferkifvbryonlouqzrxxjkoqgkqvstrsdzzvfuwspzadojkmoauvgykspsyoikrkwvijfyghymsdeqslabyvgbcaahdwvtyjlfbitzyppvbqzspoixthzfcxnuettoechbmcwafeenolbfxuwpmujqiniuwltkiszwywapmqwzkcyxfbsiyjmqkukwxbgjzszoxklvphegtfxufwnkgtahtgtbdjjewunoyfenboayeahltczgxzvnqqrjujoaguuepiamnfusepeihncctlrlumigbepjozniqvtgovreflrxbsgnxsjszdwruvdnxjwhfsbjekrbdfevgmgkjgpypkdybewzokuhxesvgkuthvnmkiizmcfwypyqqbmbserplkwtvhnxhgoftyfetnovuhcvtysmryrtmyqfa...
  1. 所以我不得不看起了题解
    题解在判断回文串时,采用了双指针
    我没考虑到的简化算法为,若return true,共有四种可能:
    (1)a ; (2)b ; (3)apre+bsuf ; (4)bpre+asuf
    前两种可能,则为a或b为回文串
    第三种可能,若apre长度大于bsuf,则我们将二者长的减短的,得到差值d,
    那么apre[0,an-d-1]与bsuf[d,bn-1]为倒序相等,而apre[an-d-1,an-1]自身为回文串,第四种可能同理
    故我们设置头尾双指针,依次判断a的头与b的尾是否相等,第一次出现不等时,则分割出判断过的字符串二者倒序相等,现在只需判断中间部分是否回文即可,而中间部分可能来自于a,也可能来自于b,故我们要判断两次
    上代码
class Solution {
    public boolean checkPalindromeFormation(String a, String b) {
        return checkPalindromef(a,b) || checkPalindromef(b,a);
    }
    public boolean checkPalindromef(String a, String b) {
        int left = 0, right = a.length()-1;
        while(left<right && a.charAt(left) == b.charAt(right)){
            left ++;
            right --;
        }
        if(left>=right){
            return true; //说明字符串a与字符串b倒序相等,K=n/2必能组成回文
        }
        return checkPalindrome(a,left,right) || checkPalindrome(b,left,right);
    }
    private boolean checkPalindrome(String a,int left,int right){
        while(left<right){
            if(a.charAt(left) != a.charAt(right)){
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
}

看了底下“小懒鼠”的评论之后真是豁然开朗 --

 /*
    首先,题目里说只有aprefix+bsuffix和bprefix+aprefix,这两种形式合规,而且允许空。
    那么合规的就有四种可能: 
    1. a
    2. b
    3. aprefix+bsuffix
    4. bprefix+asuffix
    所以只要将这四种情况都计算一下就可以了。
    重点讨论下3,4也是一样的。
    假设aprefix.length()>bsuffix.length(), 其中aprefix+bsuffix可以分成[0,l],[l+1,m],[m+1,n]这三段,[m+1,n]就是bsuffix,[0,l]是aprefix的前半部分。
    一般的,[0,l] [m+1,n]这两段是要互为回文的,[l+1,m]是要自身回文的。[l+1,m]这一段要么来自于a,要么来自于b,要么为空。
    因为都是从两端遍历,所以可以使用双指针。对于3的条件,在[0,l][m+1,n]这两段上要满足a[i]==b[j],
    若是不满足这个条件,那对应的应该是在[l+1,m]这一段上,而这一段要满足a[i]==b[j] || b[i]==b[j],否则3的情况不成立。
    4同理。
    需要判断不成立的条件。
    上面四种可能对应的flag:
    1. a [-,0,-,-] - 表示该位置可能是0也可能是1
    2. b [0,-,-,-]
    3. aprefix+bsuffix [0,0,-,0]
    4. bprefix+asuffix [0,0,0,-]
    */

标签:String,--,算法,bsuffix,字符串,bprefix,aprefix,回文
From: https://www.cnblogs.com/haipali/p/17231407.html

相关文章

  • how to install and use docker in ubuntu20.04
    sudoapt-getremovedockerdocker-enginedocker.iocontainerdrunc安装Docker之前,确保之前安装的Docker已经删除。这行命令是为了卸载系统上已经安装的Docker引......
  • 项目上线的整个过程的详细讲解以及步骤(保姆级教程)
    目录一、项目上线的架构图二、购买与服务器(阿里云)三、回顾一下基本Linux命令吧四、安装MySQL数据库五、安装Redis数据库六、安装Python3.8七、安装uwsgi八、安装虚拟环境......
  • Qt坐标点
    QLineline(QPoint(100,200),QPoint(150,210));QLinenewLine=line.translated(20,20);qDebug()<<"平移之前的坐标点:"<<line;qDebug()<<"平移之后的坐标点:"......
  • Tree Depth P 题解
    TreeDepth题意\(~~~~\)对一个排列建立小根笛卡尔树,定义第\(i\)个位置的权值为其在笛卡尔树上的深度。求对于所有恰好有\(k\)个逆序对的排列,每个位置的权值和对一......
  • webpack原理(2):ES6 module在Webpack中如何Tree-shaking构建
    Tree-shaking最早由打包工具Rollup 提出DCE作用于模块内(webpack的DCE通过UglifyJS完成),而Tree-shaking则是在打包的时候通过模块之间的信息打包必须的代码。We......
  • C语言_求最大公约数和最小公倍数
    #include<stdio.h>intmain(){ intn1,n2,x,y,temp;printf("请输入两个数用空格隔开:\n"); scanf("%d%d",&n1,&n2); x=n1>n2?n1:n2;//保存较大数 y=n1+n2-x; ......
  • IEC60870 库扩展功能-读多个参数
    1、效果2、扩展后调用代码caseC_RS_NA_1://读取参数//获取请求的地址printf("ReadParam:%d,datasize:%d\n",CS101_ASDU_getTypeID(asdu),CS101......
  • ArcGIS Runtime for Android 1 开发环境部署
    AndroidStudio,与VisualStudio一样同为开发IDE,但它对国内的友好程度却不如VisualStudio,所有,有必要记录一下安装部署的主要步骤和注意事项。一、完全清理如果未安装过An......
  • 动态规划之背包问题
    背包问题1.01背包问题有N件物品和一个容量是V的背包。每件物品只能使用一次。第i件物品的体积是\(v_i\),价值是\(w_i\)。求解将哪些物品装入背包,可使这些物品的总体......
  • webpack原理(3):Tapable源码分析及钩子函数作用分析
    webpack本质上是一种事件流的机制,它的工作流程就是将各个插件串联起来,而实现这一切的核心就是Tapable,webpack中最核心的负责编译的Compiler和负责创建bundles的Compilation......