问题描述
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.
原问题链接:https://leetcode.com/problems/longest-palindromic-substring/
问题分析
这个问题的目标是求一个字符串里最长的回文子串。那么什么是回文串呢?我们来看一些示例。从最基本的开始,比如空串:"", 长度为1的字符串,像"a", "b", "c", " "等。对于更长一些的字符串呢?
比如长度为偶数的串,像"aa", "abba",这种的情况恰好将整个串分成相等的两个部分,我们只需要从最中间的两个点开始往两头遍历比较就可以了。还有一种情况,对于长度为奇数的串,像"aba", "aabaa"等。这种的查找方式则是首先找到最中心的点,然后分别从这个点的前面一个位置和后面一个位置这两个点向两头遍历比较。
这个时候,如果我们来构造这个程序,可以从字符串s的开头到结尾的每个元素,按照前面的两种方式去向前向后遍历查找符合条件的回文。假设当前位置的索引为i, 往前往后的两个元素分别为l, r。查找可以继续的条件无非是l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)。这样我们就构造了这么一个循环。在循环里每次和我们给定的全局变量maxLen比较。如果找到的长度大于maxLen,则将maxLen设置成我们当前的长度。而当前的长度值就是r - l + 1。
按照前面的讨论,我们可以得到一个如下的程序:
public class Solution { public String longestPalindrome(String s) { if(s == null || s.length() <= 1) return s; int start = 0, end = 0, maxLen = 1; for(int i = 0; i < s.length(); i++) { int l = i - 1, r = i + 1; while(l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) { if(r - l + 1 > maxLen) { maxLen = r - l + 1; start = l; end = r; } l--; r++; } l = i; r = i + 1; while(l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) { if(r - l + 1 > maxLen) { maxLen = r - l + 1; start = l; end = r; } l--; r++; } } return s.substring(start, end + 1); } }
这里,我们声明了3个变量,start, end, maxLen。分别表示求得的当前最大回文的起始点,终结点以及长度。后面的两个循环里,每次通过设定l, r的两个起始位置,然后进行比较和设定。这样可以得到最终最长的回文子串。程序里还有一个值得注意的地方就是对于程序一些边界条件的判断。比如s == null || s.length() <= 1。对于这种情况我们可以直接返回s。
如果从纯粹对付这个程序问题的角度来说,上述程序已经够了。但是从改善代码的角度来说,如果我们希望能够写得更加简洁,上述代码还是有很多可以改进的地方的。我们一一看过来。
首先一个就是上面的两个循环基本上是干差不多的事情的,无非就是它们遍历的两个点的起始值不一样。我们完全可以把它们提出来作为一个方法。这样只要将不同的值作为参数传进去就可以了。当然,这样将这些重复的部分提出来作为一个方法之后,原来设定的几个变量像start, end, maxLen必须设置成类的成员变量。
另外一个,我们比较的时候是取的r - l + 1和maxLen。而实际上我们真的有必要专门用maxLen这个变量吗?已经有了start, end之后maxLen本身就是等于end - start + 1的。所以实际上我们完全可以用r - l + 1和end - start + 1来比较。既然只是比较它们的差,两边的这个加一其实也就没有必要了。这样我们可以得到一个简洁很多的代码:
public class Solution { int start = 0, end = 0; public String longestPalindrome(String s) { if(s == null || s.length() <= 1) return s; for(int i = 0; i < s.length(); i++) { updateLongest(i - 1, i + 1, s); updateLongest(i, i + 1, s); } return s.substring(start, end + 1); } private void updateLongest(int l, int r, String s) { while(l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) { if(r - l > end - start) { start = l; end = r; } l--; r++; } } }
总结
这个问题本身并不难。主要是针对几种情况的讨论,在字符串为空,长度小于等于1以及长度为奇数和偶数的情况下怎么去判断筛选。这里选择的循环的条件就比较讲究。另外,如果我们去想办法改进代码,会发现完全可以采用一种很简洁的方式解决这个问题。这种简约的美,你懂的:)
相关推荐
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. Java AC 版本
leetcode 分类leetcode ...Palindromic Substring 链表 #2:Add Two Numbers 分而治之 #53:Maximum Subarray 队列/集 #3:Longest Substring Without Repeating Characters 优先队列 #23:Merge k Sorted Lists
c c语言_leetcode 0005_longest_palindromic_substring.zip
Longest-Palindromic-Substring(最长回文子串) 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 Sample 1 输入: "babad" 输出: "bab" 注意: "aba" 也是一个有效答案。 Sample 2 输入...
Palindromic Substring 8 String to Integer 11 Container with Most Water 14 Longest Common Prefix 15 Three Sum 16 Three Sum Closest 20 Valid Parentheses 26 Remove Duplicates from Sorted Array 48 Rotate ...
c语言入门 c语言_leetcode题解05-longest-palindromic-substring.c
Palindromic Substring - 字数组余数:523. Continuous Subarray Sum - 无重复字符的最长子串:3. Longest Substring Without Repeating Characters - 最小跳跃步数问题 - 动态规划 + 循环策略优化:45. Jump Game ...
leetcode 知乎 此项目介绍 此项目旨在是为leetcode里面的习题提供解析(数据结构相关知识),锻炼了自己,同时也给别人带来了方便。...Palindromic Substring ZigZag Conversion Reverse Integer Strin
Palindromic Substring [Medium] LC5: Median Of Two Sorted Arrays [Hard] LC6: Zigzag Conversion [Medium] LC7: Reverse Integer [Easy] LC8: String To Integer Atoi [Medium] LC9: Palindrome Number [Easy] LC...
java入门 java_leetcode题解之005_Longest_Palindromic_Substring
Palindromic Substring :star: :star: :star: 最长回文子串,Manacher算法 0010 RegularExpressionMatching :star: :star: :star: 正则表达式匹配,dp 0012 Integer to Roman :star: 数组 0013 Roman to Integer :...
Palindromic Substring 7. Reverse Integer 9. Palindrome Number 11. Container With Most Water 12. Integer to Roman 13. Roman to Integer 14. Longest Common Prefix 15. 3Sum 20. Valid Parentheses 21. Merge...
leetcode信封 ...Palindromic Substring │ RansomNote.java //383. Ransom Note │ RussianDollEnvelope.java //354. Russian Doll Envelopes │ SlidingWindowMaximum.java //239. Sliding Window Maximum
LeetCode刷题总结 1.Two Sum 2.Add Two Numbers 3.Longest Substring Without Repeating Characters 4.Median of Two Sorted Arrays 5.Longest Palindromic Substring (Manacher算法待完成) 6.ZigZag Conversion 7....
js js_leetcode题解之5-longest-palindromic-substring.js
leetcode双人赛LeetCode 编号 题目 难度 题型 备注 Two Sum 简单 Add Two Numbers 中等 链结串列 重要 Longest Substring Without Repeating Characters 中等 字串 重要 Median of Two Sorted Arrays 困难 数学 ...
Palindromic Substring Interleaving String Triangle Distinct Subsequences Decode Ways Palindrome Partitioning II Maximal Rectangle ###Recursion N-Queens N-Queens II Balanced Binary Tree Binar
Palindromic Substring 中等 6 ZigZag Conversion 中等 7 Reverse Integer 简单 8 String to Integer (atoi) 中等 9 Palindrome Number 简单 11 Container With Most Water 中等 12 Integer to Roman 中等 13 Roman ...
Palindromic Substring 最长回文子串 string,dp 8 String to Integer(atoi) 字符串转整数 string 13 Roman to Integer 罗马数字转整数 number,string 14 Longest Common Prefix 最长公共前缀 string 16 3Sum Closest...
leetcode ...Palindromic Substring Medium com.bcat.algorithms.medium.LongestPalindromSol 6 ZigZag Conversion Medium com.bcat.algorithms.medium.ZigZagConversionSol 7 Reverse Integer Easy ...