删除部分字符使其变成回文串问题——最长公共子序列(LCS)问题
实在是汗颜,网上做一道题半天没进展:
给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
输出需要删除的字符个数。
首先是自己大致上能明白应该用动态规划的思想否则算法复杂度必然过大。可是对于回文串很难找到其状态和状态转移方程,换句话说就是:某个序列是不是回文串和这个序列的子序列没有明显关系,一个序列是回文串再加上一个字母可能就不是了。所以其状态很难找。
最近没有太多时间,不能在一个问题上闭门造车(后来来看其实也对,这种问题是计算机系的课堂例题,单纯自己苦想比较难想到)。
思路是:反序这个字符串,求这个新串和原串的最大子序列。abcda--->adcba 最大子序列是aca,再相减就是最少的字符删除个数。所以问题变成了求两个字符串的最长子序列。
那么怎么求两个字符串的最长子序列呢?既然是用动态规划,最重要的是确定状态和状态转移方程。
状态:当str1的下标为m,str2的下标是n的时候(不考虑后面的),此时的最长子序列长度L。
转移方程:1,如果str1(m)==str2(n),那么L(m,n)=L(m-1,n-1)+1。2,如果str1(m)!=str2(n),那么L(m,n)=max(L(m-1,n),L(m,n-1))
解释一下,假如m和n相等,那么这个时候最长子序列无疑是前一个L(m-1,n-1)加上1,因为这两个字符串这个地方的字符都可以加入到最长子序列里面去。如果不相等,那么要么舍弃新来的来自str1的那个字符m号,要么舍弃str2的n号字符(最长子序列每个位置上当然都是唯一确定的一个字符),舍弃之后呢,就从
L(m-1,n),L(m,n-1)当中挑一个好的(能更长的)为当前状态的最长子序列。
代码:
import java.util.Scanner; public class Main {
public static void main(String[] args) {
Solution s = new Solution();
Scanner sc = new Scanner(System.in);
while(sc.hasNextLine()) {
System.out.println( s.getResult(sc.nextLine()) );
}
sc.close();
}
} class Solution {
public int getResult(String s) {
StringBuilder s1 = new StringBuilder(s);
StringBuilder s2 = new StringBuilder(s).reverse();
return s.length() - LCS(s1, s2);
}
public int LCS(StringBuilder s1, StringBuilder s2) {
int m = s1.length();
int n = s2.length();
int[][] mutrix = new int[m + 1][n + 1]; for(int i = 1; i <= m; i++) {
for(int j = 1; j <= n; j++) {
if(s1.charAt(i - 1) == s2.charAt(j - 1))
mutrix[i][j] = mutrix[i - 1][j - 1] + 1;
else
mutrix[i][j] = Math.max(mutrix[i - 1][j], mutrix[i][j - 1]);
}
}
return mutrix[m][n];
}
}
以上代码都很好明白,就解释一下mutrix二位数组的作用,首先mutrix[m][n]表示第一个数组到m,第二个数组到n,这种情况下的最长子序列长度。如果没有这个能计算吗?可是可以,不过会导致类似用3行代码计算斐波那契数列的问题,产生巨量的重复运算(使用递归)。同时mutrix的存在可以使得我们回溯出最长子序列的值
删除部分字符使其变成回文串问题——最长公共子序列(LCS)问题的更多相关文章
- Codeforces Round #410 (Div. 2) A. Mike and palindrome【判断能否只修改一个字符使其变成回文串】
A. Mike and palindrome time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- 判断一个字符串在至多删除k个字符后是否为回文串
转自: http://www.careercup.com/question?id=6287528252407808 问题描述: A k-palindrome is a string which tra ...
- poj 1159 dp回文串
题意:添加最少的字符使之成为回文串 #include<cstdio> #include<iostream> #include<algorithm> #include ...
- uva 10453 【回文串区间dp】
Uva 10453 题意:给定字符串,问最少插入多少个字符使其变成回文串,并任意输出一种结果. 题解:和Uva 10739类似,这里是只能增加.类似定义dp[i][j]表示子串Si...Sj变为回文串 ...
- [LeetCode] Shortest Palindrome 最短回文串
Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...
- POJ 1159 回文串-LCS
题目链接:http://poj.org/problem?id=1159 题意:给定一个长度为N的字符串.问你最少要添加多少个字符才能使它变成回文串. 思路:最少要添加的字符个数=原串长度-原串最长回文 ...
- cf1140E 回文串+染色方案dp
有点硬核的dp..要用到一个结论.. /* 把原串拆成奇偶串,再拆成极大连续的-1串:该串两端都是非-1数,中间都是-1,并且下标要么都是偶数,要么都是技术 然后对所有这些串进行dp,dp[i][0] ...
- 牛客寒假算法基础集训营4 I题 Applese 的回文串
链接:https://ac.nowcoder.com/acm/contest/330/I 来源:牛客网 自从 Applese 学会了字符串之后,精通各种字符串算法,比如--判断一个字符串是不是回文串. ...
- 集训第五周动态规划 G题 回文串
Description A palindrome is a symmetrical string, that is, a string read identically from left to ri ...
随机推荐
- Touch ID使用
前言:如果图片看不了请移步:简书 Touch ID简介 Touch ID指纹识别作为iPhone 5s上的"杀手级"功能早已为人们所熟知,目前搭载的设备有iphone SE.iPh ...
- iOS MJRefresh设置MJRefreshStateNoMoreData状态图片
MJRefresh地址 // 代码地址: https://github.com/CoderMJLee/MJRefresh// 代码地址: http://code4app.com/ios/%E5%B ...
- git rebase与 git合并(error: failed to push some refs to)解决方法
1.遇到的问题 本地有一个git仓库,在github上新建了一个空的仓库,但是更新了REWADME.md的信息,即在github上多了一个提交. 关联远程仓库,操作顺序如下: git remote a ...
- Dictionary摘抄
Dictionary,字典,键值对集合. 下面的代码示例创建一个空的带有字符串键的字符串 Dictionary,并使用 Add 方法添加一些元素.该示例演示在尝试添加重复的键时 Add 方法引发Arg ...
- ORACLE opatch命令学习实践
opatch 是ORACLE开发的用来安装,卸载,检测patch冲突.管理ORACLE所有已经安装的补丁的工具,当然这是一个命令工具.opatch命令工具一般位于$ORACLE_HOME/OPat ...
- MongoDB学习笔记~大叔框架实体更新支持N层嵌套~递归递归我爱你!
回到目录 递归递归我爱你!只要你想做,就一定能成功! 从一到二,从二到三,它是容易的,也是没什么可搞的,或者说,它是一种流水线的方式,而从三到十,从十到百,它注定要有一个质的突破,否则,它会把你累死, ...
- android 拔打电话功能
private void phoneCall(String num) { String phoneNum = "tel:" + num; Uri smsToUri = Uri.pa ...
- hadoop2.2.0伪分布式搭建3--安装Hadoop
3.1上传hadoop安装包 3.2解压hadoop安装包 mkdir /cloud #解压到/cloud/目录下 tar -zxvf hadoop-2.2.0.tar.gz -C /cloud/ 3 ...
- Vsphere初试——基本安装
现有工具: 一台Dell PowerEdge R820服务器 VMware-VMvisor-Installer-5.5.0.update01-1623387.x86_64(ESXi).iso VMwa ...
- [转]一种简单的js时间控件
使用方法: 粘贴代码到文本文档中,文档名称为datetime.js,然后在html文件中引用如下代码即可 <input name="shijian1" id="sh ...