本文主要介绍作者对最长回文子串问题( Longest Palindromic Substring)的动态规划解法(DP solution),作者leetcode上的提交结果为accept。
前言
本文主要介绍作者对最长回文子串问题( Longest Palindromic Substring)的动态规划解法(DP solution),作者leetcode上的提交结果为accept。作者之前也采用了DP算法解决这个问题,但多次都不能accept,提交结果为TLE(time limit exceeded)。作者经过多次修改才成功,所以希望把自己的成功代码贡献出来。作者的失败经验与反思见后。
问题描述
以下描述摘抄自leetcode:问题链接在此
Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.
算法描述
定义 P[ i, j ] ← true 如果S的子串 Si … Sj 是一个回文子串, 否则值为false.
故有:
(1) P[ i, j ] ← ( P[ i+1, j-1 ] 且 Si = Sj )
初始情况:
(2) P[ i, i ] ← true
(3) P[ i, i+1 ] ← ( Si = Si+1 )
定义一个start,len用以存储找到最大回文子串时,子串开始的位置与结束的位置
java代码
public String longestPalindrome(String s) {
int n=s.length();
String longest="";
if(n==0||n==1) return s;
boolean dp[][]=new boolean[1005][1005];
int start=0,len=0;
//初始化,见式子(2)
for(int i=0;i<n;i++) {dp[i][i]=true; }
//子串长度为2的赋值,见式子(3)
for(int i=0;i<n-1;i++){
if(s.charAt(i)==s.charAt(i+1)){
dp[i][i+1]=true;
//如果有多个子串长度为2,该判断语句可以减少赋值次数。
//注意题目中说最长回文子串是唯一的,故可以这么做。
if(len<2){
start=i;
len=2;
}
}
else dp[i][i+1]=false;
}
//赋值,见式子(1),strlen表示当前遍历的子字符串的长度,最大为n
for(int strlen=3;strlen<=n;strlen++){
for(int i=0;i<n-strlen+1;i++){
if(s.charAt(i+strlen-1)==s.charAt(i)){
//是否为回文子串取决于内部的子串,故有可能不是回文子串
dp[i][i+strlen-1]=dp[i+1][i+strlen-1-1];
//注意判断条件一定要判断该字串是否为回文子串
if(dp[i][i+strlen-1] && strlen>len){
start=i;len=strlen;
}
}else dp[i][i+strlen-1]=false;
}
}
//调试信息:System.out.println(start+" "+len+" s.length="+s.length());
longest=s.substring(start, start+len);
//调试信息:System.out.println(longest.length());
return longest;
}
作者反思
我的代码多次出现TLE的提示,可能遇到过的问题
dp[i]的类型为int,判断比较的速度慢于boolean类型
初始的寻找最大回文子串方式是每次判断到长度变大,就调用一次s.substring(start,end)大大增加了开销,最后修改后决定采用保存开始位置start与长度len的方法。
在子串长度为1和2时不必要地对start与len赋值,现在加上了判断条件。
参考链接
http://articles.leetcode.com/longest-palindromic-substring-part-i/
@font-face {
font-family: octicons-anchor;
src: url(data:font/woff;charset=utf-8;base64,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) format('woff');
}
#cnblogs_post_body {
margin: 20px 0;
}
.cnblogs-markdown {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
color: #333;
overflow: hidden;
font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
font-size: 16px;
line-height: 1.6;
word-wrap: break-word;
}
.cnblogs-markdown a {
background: transparent;
}
.cnblogs-markdown a:active,
.cnblogs-markdown a:hover {
outline: 0;
}
.cnblogs-markdown strong {
font-weight: bold;
}
.cnblogs-markdown h1 {
font-size: 2em;
margin: 0.67em 0;
}
.cnblogs-markdown img {
border: 0;
}
.cnblogs-markdown hr {
box-sizing: content-box;
height: 0;
}
.cnblogs-markdown pre {
overflow: auto;
}
.cnblogs-markdown code,
.cnblogs-markdown kbd,
.cnblogs-markdown pre {
font-family: monospace, monospace;
font-size: 1em;
}
.cnblogs-markdown input {
color: inherit;
font: inherit;
margin: 0;
}
.cnblogs-markdown html input[disabled] {
cursor: default;
}
.cnblogs-markdown input {
line-height: normal;
}
.cnblogs-markdown input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
.cnblogs-markdown table {
border-collapse: collapse;
border-spacing: 0;
}
.cnblogs-markdown td,
.cnblogs-markdown th {
padding: 0;
}
.cnblogs-markdown * {
box-sizing: border-box;
}
.cnblogs-markdown input {
font: 13px/1.4 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol";
}
.cnblogs-markdown a {
color: #4183c4;
text-decoration: none;
}
.cnblogs-markdown a:hover,
.cnblogs-markdown a:active {
text-decoration: underline;
}
.cnblogs-markdown hr {
height: 0;
margin: 15px 0;
overflow: hidden;
background: transparent;
border: 0;
border-bottom: 1px solid #ddd;
}
.cnblogs-markdown hr:before {
display: table;
content: "";
}
.cnblogs-markdown hr:after {
display: table;
clear: both;
content: "";
}
.cnblogs-markdown h1,
.cnblogs-markdown h2,
.cnblogs-markdown h3,
.cnblogs-markdown h4,
.cnblogs-markdown h5,
.cnblogs-markdown h6 {
margin-top: 15px;
margin-bottom: 10px;
line-height: 1.1;
}
.cnblogs-markdown blockquote {
margin: 0;
}
.cnblogs-markdown ul,
.cnblogs-markdown ol {
padding: 0;
margin-top: 0;
margin-bottom: 0;
}
.cnblogs-markdown ol ol,
.cnblogs-markdown ul ol {
list-style-type: lower-roman;
}
.cnblogs-markdown ul ul ol,
.cnblogs-markdown ul ol ol,
.cnblogs-markdown ol ul ol,
.cnblogs-markdown ol ol ol {
list-style-type: lower-alpha;
}
.cnblogs-markdown dd {
margin-left: 0;
}
.cnblogs-markdown code {
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 12px;
}
.cnblogs-markdown pre {
margin-top: 0;
margin-bottom: 0;
font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace;
}
.cnblogs-markdown .octicon {
font: normal normal normal 16px/1 octicons-anchor;
display: inline-block;
text-decoration: none;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.cnblogs-markdown .octicon-link:before {
content: '\f05c';
}
.cnblogs-markdown>*:first-child {
margin-top: 0 !important;
}
.cnblogs-markdown>*:last-child {
margin-bottom: 0 !important;
}
.cnblogs-markdown a:not(:link):not(:visited) {
color: inherit;
text-decoration: none;
}
.cnblogs-markdown .anchor {
position: absolute;
top: 0;
left: 0;
display: block;
padding-right: 6px;
padding-left: 30px;
margin-left: -30px;
}
.cnblogs-markdown .anchor:focus {
outline: none;
}
.cnblogs-markdown h1,
.cnblogs-markdown h2,
.cnblogs-markdown h3,
.cnblogs-markdown h4,
.cnblogs-markdown h5,
.cnblogs-markdown h6 {
position: relative;
margin-top: 1em;
margin-bottom: 16px;
font-weight: bold;
line-height: 1.4;
}
.cnblogs-markdown h1 .octicon-link,
.cnblogs-markdown h2 .octicon-link,
.cnblogs-markdown h3 .octicon-link,
.cnblogs-markdown h4 .octicon-link,
.cnblogs-markdown h5 .octicon-link,
.cnblogs-markdown h6 .octicon-link {
display: none;
color: #000;
vertical-align: middle;
}
.cnblogs-markdown h1:hover .anchor,
.cnblogs-markdown h2:hover .anchor,
.cnblogs-markdown h3:hover .anchor,
.cnblogs-markdown h4:hover .anchor,
.cnblogs-markdown h5:hover .anchor,
.cnblogs-markdown h6:hover .anchor {
padding-left: 8px;
margin-left: -30px;
text-decoration: none;
}
.cnblogs-markdown h1:hover .anchor .octicon-link,
.cnblogs-markdown h2:hover .anchor .octicon-link,
.cnblogs-markdown h3:hover .anchor .octicon-link,
.cnblogs-markdown h4:hover .anchor .octicon-link,
.cnblogs-markdown h5:hover .anchor .octicon-link,
.cnblogs-markdown h6:hover .anchor .octicon-link {
display: inline-block;
}
.cnblogs-markdown h1 {
padding-bottom: 0.3em;
font-size: 2.25em !important;
line-height: 1.2;
border-bottom: 1px solid #eee;
}
.cnblogs-markdown h1 .anchor {
line-height: 1;
}
.cnblogs-markdown h2 {
padding-bottom: 0.3em;
font-size: 1.75em !important;
line-height: 1.225;
border-bottom: 1px solid #eee;
}
.cnblogs-markdown h2 .anchor {
line-height: 1;
}
.cnblogs-markdown h3 {
font-size: 1.5em!important;
line-height: 1.43;
}
.cnblogs-markdown h3 .anchor {
line-height: 1.2;
}
.cnblogs-markdown h4 {
font-size: 1.25em !important;
}
.cnblogs-markdown h4 .anchor {
line-height: 1.2;
}
.cnblogs-markdown h5 {
font-size: 1em !important;
}
.cnblogs-markdown h5 .anchor {
line-height: 1.1;
}
.cnblogs-markdown h6 {
font-size: 1em !important;
color: #777;
}
.cnblogs-markdown h6 .anchor {
line-height: 1.1;
}
.cnblogs-markdown p,
.cnblogs-markdown blockquote,
.cnblogs-markdown ul,
.cnblogs-markdown ol,
.cnblogs-markdown dl,
.cnblogs-markdown table,
.cnblogs-markdown pre {
margin-top: 0;
margin-bottom: 16px;
}
.cnblogs-markdown hr {
height: 4px;
padding: 0;
margin: 16px 0;
background-color: #e7e7e7;
border: 0 none;
}
.cnblogs-markdown ul,
.cnblogs-markdown ol {
padding-left: 2em;
font-size: 14px;
}
.cnblogs-markdown ul ul,
.cnblogs-markdown ul ol,
.cnblogs-markdown ol ol,
.cnblogs-markdown ol ul {
margin-top: 0;
margin-bottom: 0;
}
.cnblogs-markdown li>p {
margin-top: 16px;
}
.cnblogs-markdown dl {
padding: 0;
}
.cnblogs-markdown dl dt {
padding: 0;
margin-top: 16px;
font-size: 1em;
font-style: italic;
font-weight: bold;
}
.cnblogs-markdown dl dd {
padding: 0 16px;
margin-bottom: 16px;
}
.cnblogs-markdown blockquote {
color: #333;
padding: 10px 15px;
border: none;
border-left: 10px solid #D6DBDF;
}
.cnblogs-markdown blockquote>:first-child {
margin-top: 0;
}
.cnblogs-markdown blockquote>:last-child {
margin-bottom: 0;
}
.cnblogs-markdown table {
display: block;
width: 100%;
overflow: auto;
word-break: normal;
word-break: keep-all;
}
.cnblogs-markdown table th {
font-weight: bold;
}
.cnblogs-markdown table th,
.cnblogs-markdown table td {
padding: 6px 13px;
border: 1px solid #ddd;
}
.cnblogs-markdown table tr {
background-color: #fff;
border-top: 1px solid #ccc;
}
.cnblogs-markdown table tr:nth-child(2n) {
background-color: #f8f8f8;
}
.cnblogs-markdown img {
max-width: 100%;
box-sizing: border-box;
}
.cnblogs-markdown code {
padding: 0;
padding-top: 0.2em;
padding-bottom: 0.2em;
margin: 0;
font-size: 85%;
background-color: rgba(0,0,0,0.04);
border-radius: 3px;
border: none !important;
display: inline-block;
}
.cnblogs-markdown code:before,
.cnblogs-markdown code:after {
letter-spacing: -0.2em;
content: "\00a0";
}
/*only for syntaxhighlighter */
/*--start--*/
.cnblogs-markdown .syntaxhighlighter table td.code {
width:95% !important;
}
.cnblogs-markdown .syntaxhighlighter code {
font-family: "Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace!important;
padding: 0 !important;
border-radius: 0 !important;
background-color: transparent !important;
}
.cnblogs-markdown .syntaxhighlighter code:before,
.cnblogs-markdown .syntaxhighlighter code:before {
letter-spacing: -0.5em;
}
/*--end--*/
.cnblogs-markdown pre>code {
padding: 0;
margin: 0;
font-size: 100%;
word-break: normal;
white-space: pre;
background: transparent;
border: 0;
}
.cnblogs-markdown .highlight {
margin-bottom: 16px;
}
.cnblogs-markdown .highlight pre,
.cnblogs-markdown pre {
padding: 16px;
overflow: auto;
font-size: 85%;
line-height: 1.45;
background-color: #f7f7f7;
border-radius: 3px;
}
.cnblogs-markdown .highlight pre {
margin-bottom: 0;
word-break: normal;
}
.cnblogs-markdown pre {
word-wrap: normal;
}
.cnblogs-markdown pre code {
display: inline;
max-width: initial;
padding: 0;
margin: 0;
overflow: initial;
line-height: inherit;
word-wrap: normal;
background-color: transparent;
border: 0;
}
.cnblogs-markdown pre code:before,
.cnblogs-markdown pre code:after {
content: normal;
}
.cnblogs-markdown kbd {
display: inline-block;
padding: 3px 5px;
font-size: 11px;
line-height: 10px;
color: #555;
vertical-align: middle;
background-color: #fcfcfc;
border: solid 1px #ccc;
border-bottom-color: #bbb;
border-radius: 3px;
box-shadow: inset 0 -1px 0 #bbb;
}
.cnblogs-markdown .pl-c {
color: #969896;
}
.cnblogs-markdown .pl-c1,
.cnblogs-markdown .pl-mdh,
.cnblogs-markdown .pl-mm,
.cnblogs-markdown .pl-mp,
.cnblogs-markdown .pl-mr,
.cnblogs-markdown .pl-s1 .pl-v,
.cnblogs-markdown .pl-s3,
.cnblogs-markdown .pl-sc,
.cnblogs-markdown .pl-sv {
color: #0086b3;
}
.cnblogs-markdown .pl-e,
.cnblogs-markdown .pl-en {
color: #795da3;
}
.cnblogs-markdown .pl-s1 .pl-s2,
.cnblogs-markdown .pl-smi,
.cnblogs-markdown .pl-smp,
.cnblogs-markdown .pl-stj,
.cnblogs-markdown .pl-vo,
.cnblogs-markdown .pl-vpf {
color: #333;
}
.cnblogs-markdown .pl-ent {
color: #63a35c;
}
.cnblogs-markdown .pl-k,
.cnblogs-markdown .pl-s,
.cnblogs-markdown .pl-st {
color: #a71d5d;
}
.cnblogs-markdown .pl-pds,
.cnblogs-markdown .pl-s1,
.cnblogs-markdown .pl-s1 .pl-pse .pl-s2,
.cnblogs-markdown .pl-sr,
.cnblogs-markdown .pl-sr .pl-cce,
.cnblogs-markdown .pl-sr .pl-sra,
.cnblogs-markdown .pl-sr .pl-sre,
.cnblogs-markdown .pl-src {
color: #183691;
}
.cnblogs-markdown .pl-v {
color: #ed6a43;
}
.cnblogs-markdown .pl-id {
color: #b52a1d;
}
.cnblogs-markdown .pl-ii {
background-color: #b52a1d;
color: #f8f8f8;
}
.cnblogs-markdown .pl-sr .pl-cce {
color: #63a35c;
font-weight: bold;
}
.cnblogs-markdown .pl-ml {
color: #693a17;
}
.cnblogs-markdown .pl-mh,
.cnblogs-markdown .pl-mh .pl-en,
.cnblogs-markdown .pl-ms {
color: #1d3e81;
font-weight: bold;
}
.cnblogs-markdown .pl-mq {
color: #008080;
}
.cnblogs-markdown .pl-mi {
color: #333;
font-style: italic;
}
.cnblogs-markdown .pl-mb {
color: #333;
font-weight: bold;
}
.cnblogs-markdown .pl-md,
.cnblogs-markdown .pl-mdhf {
background-color: #ffecec;
color: #bd2c00;
}
.cnblogs-markdown .pl-mdht,
.cnblogs-markdown .pl-mi1 {
background-color: #eaffea;
color: #55a532;
}
.cnblogs-markdown .pl-mdr {
color: #795da3;
font-weight: bold;
}
.cnblogs-markdown .pl-mo {
color: #1d3e81;
}
.cnblogs-markdown kbd {
display: inline-block;
padding: 3px 5px;
font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace;
line-height: 10px;
color: #555;
vertical-align: middle;
background-color: #fcfcfc;
border: solid 1px #ccc;
border-bottom-color: #bbb;
border-radius: 3px;
box-shadow: inset 0 -1px 0 #bbb;
padding-top: 20px;
}
.cnblogs-markdown .task-list-item {
list-style-type: none;
}
.cnblogs-markdown .task-list-item+.task-list-item {
margin-top: 3px;
}
.cnblogs-markdown .task-list-item input {
margin: 0 0.35em 0.25em -1.6em;
vertical-align: middle;
}
.cnblogs-markdown :checked+.radio-label {
z-index: 1;
position: relative;
border-color: #4183c4;
}