5. Longest Palindromic Substring
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length ofs is 1000.
Example:
Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.
Example:
Input: "cbbd"
Output: "bb"
class Solution {
public:
string longestPalindrome(string s) {
}
};
解题思路:
-
自己的解题思路
自己采用的是
Brute Force
,然后通过不断优化算法,强行
AC
。一次次优化的过程,真的很有成就感。
思路很简单,就是采用两指针,从尾开始判别,如果是回文数,哪肯定是那次循环当作最长的回文子字符串,因此直接
break;
进入下个循环。
-
别人的解题思路
Manacher’s Algorithm(
马拉车算法
)
通过加入一些无关字符,
eg:##
进行搜索;
DP
也可以做。
学习收获:
-
优化暴力法。体验一次 强行 AC 。
附件:程序
1
、自己的程序:
一开始程序如下:这些都会出现
LTE
错误,主要是测试用例给的
string
很大。
class Solution
{
public:
string longestPalindrome(string s)
{
if(s.size() == 0) { return{}; }
int max = 0;
string res;
for(int i = 0; i != s.size(); ++i)
{
//
由于
j
每次都是查看最后一个位置,其实只需要从等于
s[i]
的最后一个位置开始
for(
auto j = s.size()
; j != i; --j)
{
if(isPalindrome(s, i, j))
{
if(j - i > max)
{
max = j - i;
//
可以不需要每次取出
substr,
可以直接记录起始位置就行;因为有个
max
,所以可以就记开始位置就好
res = s.substr(i, j - i);
}
break;
}
}
}
return res;
}
//
这个可以优化,不需要全部倒序就能判别是否是回文字符串
bool
isPalindrome
(string s, int beg, int end)
{
string tem = s.substr(beg, end - beg);
reverse(tem.begin(), tem.end());
return s.substr(beg, end - beg) == tem?true:false;
}
};
之后,改为
//NOTE
:对于字符串的取值,可以直接
s[beg],
这样显得很整洁,虽然也是符号重载为迭代器实现的
bool isPalindrome(string s, int beg, int end)
{
while((end > beg) &&
*(s.begin() + beg) == *(s.begin() + end - 1)
)
{
++beg;
--end;
}
if(end > beg) return false;
else
{
return true;
}
}
通过几次优化,可以勉强通过程序,不过时间花费比较大,
509ms.
class
Solution
{
public
:
string
longestPalindrome
(
string
s
)
{
if
(
s
.
size
()
==
0
)
{
return
{};
}
int
max
=
0
;
int
beg
=
0
;
for
(
int
i
=
0
;
i
!=
s
.
size
();
++
i
)
{
for
(
auto
j
=
s
.
size
();
j
!=
i
;
--
j
)
{
j
=
s
.
find_last_of
(
s
[
i
],
j
);
//
肯定会找到
j
的,最坏的情况
j==i;
对于找到的子字符串如果长度
<=max,
那么直接跳出循环
if
(
j
+
1
-
i
<=
max
)
{
break
;
}
if
(
isPalindrome
(
s
,
i
,
j
+
1
))
{
max
=
j
+
1
-
i
;
beg
=
i
;
break
;
}
}
}
return
s
.
substr
(
beg
,
max
);
}
bool
isPalindrome
(
string
s
,
int
beg
,
int
end
)
{
while
((
end
>
beg
)
&&
s
[
beg
]
==
s
[
end
-
1
])
{
++
beg
;
--
end
;
}
if
(
end
>
beg
)
return
false
;
else
{
return
true
;
}
}
};
2
、别人的程序
运行时间
6ms
class
Solution
{
public
:
string
longestPalindrome
(
string
s
)
{
if
(
s
.
empty
())
return
""
;
if
(
s
.
size
()
==
1
)
return
s
;
int
min_start
=
0
,
max_len
=
1
;
for
(
int
i
=
0
;
i
<
s
.
size
();)
{
if
(
s
.
size
()
-
i
<=
max_len
/
2
)
break
;
int
j
=
i
,
k
=
i
;
while
(
k
<
s
.
size
()
-
1
&&
s
[
k
+
1
]
==
s
[
k
])
++
k
;
// Skip duplicate characters.
i
=
k
+
1
;
while
(
k
<
s
.
size
()
-
1
&&
j
>
0
&&
s
[
k
+
1
]
==
s
[
j
-
1
])
{
++
k
;
--
j
;
}
// Expand.
int
new_len
=
k
-
j
+
1
;
if
(
new_len
>
max_len
)
{
min_start
=
j
;
max_len
=
new_len
;
}
}
return
s
.
substr
(
min_start
,
max_len
);
}
};
string
longestPalindrome
(
string
s
)
{
if
(
s
.
length
()
==
0
||
s
.
length
()
==
1
)
return
s
;
string
max
(
""
);
for
(
int
i
=
0
;
i
<
int
(
s
.
length
())
-
1
;
i
++)
{
string
first
=
helper
(
s
,
i
,
i
);
// The center is s[i]
if
(
first
.
length
()
>
max
.
length
())
max
=
first
;
string
second
=
helper
(
s
,
i
,
i
+
1
);
// The center is s[i][i]
if
(
second
.
length
()
>
max
.
length
())
max
=
second
;
}
return
max
;
}
string
helper
(
string
s
,
int
left
,
int
right
)
{
while
(
left
>=
0
&&
right
<
int
(
s
.
length
())
&&
s
[
right
]
==
s
[
left
])
{
left
--;
right
++;
}
return
s
.
substr
(
left
+
1
,
right
-
1
-
left
);
}
Manacher’s Algorithm(
马拉车算法
)
class
Solution
{
public
:
// Transform S into T.
// For example, S = "abba", T = "^#a#b#b#a#$".
// ^ and $ signs are sentinels appended to each end to avoid bounds checking
string
preProcess
(
const
string
&
s
)
{
int
n
=
s
.
length
();
3.5
Longest Palindromic Substring
65
if
(
n
==
0
)
return
"^$"
;
string
ret
=
"^"
;
for
(
int
i
=
0
;
i
<
n
;
i
++)
ret
+=
"#"
+
s
.
substr
(
i
,
1
);
ret
+=
"#$"
;
return
ret
;
}
string
longestPalindrome
(
string
s
)
{
string
T
=
preProcess
(
s
);
const
int
n
=
T
.
length
();
int
P
[
n
];
int
C
=
0
,
R
=
0
;
for
(
int
i
=
1
;
i
<
n
-
1
;
i
++)
{
int
i_mirror
=
2
*
C
-
i
;
// equals to i' = C - (i-C)
P
[
i
]
=
(
R
>
i
)
?
min
(
R
-
i
,
P
[
i_mirror
])
:
0
;
// Attempt to expand palindrome centered at i
while
(
T
[
i
+
1
+
P
[
i
]]
==
T
[
i
-
1
-
P
[
i
]])
P
[
i
]++;
// If palindrome centered at i expand past R,
// adjust center based on expanded palindrome.
if
(
i
+
P
[
i
]
>
R
)
{
C
=
i
;
R
=
i
+
P
[
i
];
}
}
// Find the maximum element in P.
int
max_len
=
0
;
int
center_index
=
0
;
for
(
int
i
=
1
;
i
<
n
-
1
;
i
++)
{
if
(
P
[
i
]
>
max_len
)
{
max_len
=
P
[
i
];
center_index
=
i
;
}
}
return
s
.
substr
((
center_index
-
1
-
max_len
)
/
2
,
max_len
);
}
};
还有相应的
DP
解法,不在一一收集。
有兴趣的可以看看,
可能需要权限。完成这个题目,就可以解锁。