腾讯面试题-回文构造
2016-07-17 22:59
405 查看
题目描述:
给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?输出需要删除的字符个数。
输入描述:
输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.输出描述:
对于每组数据,输出一个整数,代表最少需要删除的字符个数。输入例子:
abcda输出例子:
22
思路分析:
首先求s的反串rs,然后对s和rs求最长公共子序列,要删除的字符个数就是LCS.核心代码:
求最大公共子序列
public class ComSubstr { public static void main(String[] arg) { String a = "blog.csdn.net"; String b = "csdn.blogt"; comSubstring(a, b); } private static void comSubstring(String str1, String str2) { char[] a = str1.toCharArray(); char[] b = str2.toCharArray(); int a_length = a.length; int b_length = b.length; int[][] lcs = new int[a_length + 1][b_length + 1]; // 初始化数组 for (int i = 0; i <= b_length; i++) { for (int j = 0; j <= a_length; j++) { lcs[j][i] = 0; } } for (int i = 1; i <= a_length; i++) { for (int j = 1; j <= b_length; j++) { if (a[i - 1] == b[j - 1]) { lcs[i][j] = lcs[i - 1][j - 1] + 1; } if (a[i - 1] != b[j - 1]) { lcs[i][j] = lcs[i][j - 1] > lcs[i - 1][j] ? lcs[i][j - 1] : lcs[i - 1][j]; } } } // 输出数组结果进行观察 for (int i = 0; i <= a_length; i++) { for (int j = 0; j <= b_length; j++) { System.out.print(lcs[i][j]+","); } System.out.println(""); } // 由数组构造最小公共字符串 int max_length = lcs[a_length][b_length]; char[] comStr = new char[max_length]; int i =a_length, j =b_length; while(max_length>0){ if(lcs[i][j]!=lcs[i-1][j-1]){ if(lcs[i-1][j]==lcs[i][j-1]){//两字符相等,为公共字符 comStr[max_length-1]=a[i-1]; max_length--; i--;j--; }else{//取两者中较长者作为A和B的最长公共子序列 if(lcs[i-1][j]>lcs[i][j-1]){ i--; }else{ j--; } } }else{ i--;j--; } } System.out.print("最长公共字符串是:"); System.out.print(comStr); } }
问题描述:
问题】 求两字符序列的最长公共字符子序列注意:
并不要求子串(字符串一)的字符必须连续出现在字符串二中。思路分析:
最优子结构和重叠子问题的性质都具有,所以要采取动态规划的算法
最长公共子序列的结构
设序列X=其中Xm-1=
子问题的递归结构
由最长公共子序列问题的最优子结构性质可知,要找出X=由此递归结构容易看到最长公共子序列问题具有子问题重叠性质。
例如,在计算X和Y的最长公共子序列时,可能要计算出X和Yn-1及Xm-1和Y的最长公共子序列。而这两个子问题都包含一个公共子问题,即计算Xm-1和Yn-1的最长公共子序列。与矩阵连乘积最优计算次序问题类似,我们来建立子问题的最优值的递归关系。用c[i,j]记录序列Xi和Yj的最长公共子序列的长度。其中Xi=<x1, x2, …, xi>,Yj=<y1, y2, …, yj>。
当i=0或j=0时,空序列是Xi和Yj的最长公共子序列,故c[i,j]=0。其他情况下,由定理可建立递归关系如下:
代码:
public class ComSubstr { public static void main(String[] arg) { String a = "blog.csdn.net"; String b = "csdn.blogt"; comSubstring(a, b); } private static void comSubstring(String str1, String str2) { char[] a = str1.toCharArray(); char[] b = str2.toCharArray(); int a_length = a.length; int b_length = b.length; int[][] lcs = new int[a_length + 1][b_length + 1]; // 初始化数组 for (int i = 0; i <= b_length; i++) { for (int j = 0; j <= a_length; j++) { lcs[j][i] = 0; } } for (int i = 1; i <= a_length; i++) { for (int j = 1; j <= b_length; j++) { if (a[i - 1] == b[j - 1]) { lcs[i][j] = lcs[i - 1][j - 1] + 1; } if (a[i - 1] != b[j - 1]) { lcs[i][j] = lcs[i][j - 1] > lcs[i - 1][j] ? lcs[i][j - 1] : lcs[i - 1][j]; } } } // 输出数组结果进行观察 for (int i = 0; i <= a_length; i++) { for (int j = 0; j <= b_length; j++) { System.out.print(lcs[i][j]+","); } System.out.println(""); } // 由数组构造最小公共字符串 int max_length = lcs[a_length][b_length]; char[] comStr = new char[max_length]; int i =a_length, j =b_length; while(max_length>0){ if(lcs[i][j]!=lcs[i-1][j-1]){ if(lcs[i-1][j]==lcs[i][j-1]){//两字符相等,为公共字符 comStr[max_length-1]=a[i-1]; max_length--; i--;j--; }else{//取两者中较长者作为A和B的最长公共子序列 if(lcs[i-1][j]>lcs[i][j-1]){ i--; }else{ j--; } } }else{ i--;j--; } } System.out.print("最长公共字符串是:"); System.out.print(comStr); } }
输出结果:
0,0,0,0,0,0,1,2,2,2,2, 0,0,0,0,0,0,1,2,3,3,3, 0,0,0,0,0,0,1,2,3,4,4, 0,0,0,0,0,1,1,2,3,4,4, 0,1,1,1,1,1,1,2,3,4,4, 0,1,2,2,2,2,2,2,3,4,4, 0,1,2,3,3,3,3,3,3,4,4, 0,1,2,3,4,4,4,4,4,4,4, 0,1,2,3,4,5,5,5,5,5,5, 0,1,2,3,4,5,5,5,5,5,5, 0,1,2,3,4,5,5,5,5,5,5, 0,1,2,3,4,5,5,5,5,5,6, 最长公共字符串是:csdn.t
## 我的微信二维码如下,欢迎交流讨论 ##
欢迎关注《IT面试题汇总》微信订阅号。每天推送经典面试题和面试心得技巧,都是干货!
微信订阅号二维码如下:
参考:
http://www.nowcoder.com/test/question/done?tid=3778580&qid=44802
http://www.voidcn.com/blog/Do_Know/article/p-5978576.html
<script type="text/javascript">
$(function () {
$('pre.prettyprint code').each(function () {
var lines = $(this).text().split('\n').length;
var $numbering = $('<ul/>').addClass('pre-numbering').hide();
$(this).addClass('has-numbering').parent().append($numbering);
for (i = 1; i <= lines; i++) {
$numbering.append($('<li/>').text(i));
};
$numbering.fadeIn(1700);
});
});
</script>
相关文章推荐
- 程序员的创业陷阱:接私活
- Android面试题整理(转载自 简书)
- 面试相关
- android面试相关知识
- 第147课: Spark面试经典系列之Shuffle的性能调优问题
- 猿思想
- 轻松搞定面试中的二叉树题目
- 面试题-----(StringBuffer)
- 宝剑锋从磨砺出
- mysql 面试
- 【备战面试之】五、谈扩展方法的理解
- 趣文:程序员的进化史
- 魔都 3 年,从程序员到 CTO
- 栈和队列面试题(一):栈和队列的相互实现
- 关于web前端面试题系列之必考面试题(面试官总结)
- 今日头条面试相关
- 动态规划算法详解
- ios/android 程序员
- 程序员的爱好
- 剑指offer面试题:如下为类型CMyString的声明,请为该类型添加赋值运算符函数。