`
frank-liu
  • 浏览: 1666018 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

leetcode: Longest Palindromic Substring

 
阅读更多

问题描述

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以及长度为奇数和偶数的情况下怎么去判断筛选。这里选择的循环的条件就比较讲究。另外,如果我们去想办法改进代码,会发现完全可以采用一种很简洁的方式解决这个问题。这种简约的美,你懂的:) 

分享到:
评论

相关推荐

    LeetCode5 Longest Palindromic Substring

    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:leetcode问题的代码

    leetcode 分类leetcode ...Palindromic Substring 链表 #2:Add Two Numbers 分而治之 #53:Maximum Subarray 队列/集 #3:Longest Substring Without Repeating Characters 优先队列 #23:Merge k Sorted Lists

    javalruleetcode-LeetCode::lollipop:个人LeetCode习题解答仓库-多语言

    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 ...

    leetcode跳跃-leetcode:leetcode一天一次

    Palindromic Substring - 字数组余数:523. Continuous Subarray Sum - 无重复字符的最长子串:3. Longest Substring Without Repeating Characters - 最小跳跃步数问题 - 动态规划 + 循环策略优化:45. Jump Game ...

    leetcode知乎-leetcode:leetcode解决方案

    leetcode 知乎 此项目介绍 此项目旨在是为leetcode里面的习题提供解析(数据结构相关知识),锻炼了自己,同时也给别人带来了方便。...Palindromic Substring ZigZag Conversion Reverse Integer Strin

    leetcode2sum-Problems:编程问题的回购

    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...

    leetcode卡-LeetCode:LeetCode题解

    Palindromic Substring :star: :star: :star: 最长回文子串,Manacher算法 0010 RegularExpressionMatching :star: :star: :star: 正则表达式匹配,dp 0012 Integer to Roman :star: 数组 0013 Roman to Integer :...

    lrucacheleetcode-leetcode:leetcode

    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信封-LeetCode:LeetCode解题

    leetcode信封 ...Palindromic Substring │ RansomNote.java //383. Ransom Note │ RussianDollEnvelope.java //354. Russian Doll Envelopes │ SlidingWindowMaximum.java //239. Sliding Window Maximum

    leetcode338-LeetCode:LeetCode刷题总结

    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....

    leetcode双人赛-LeetCode:力扣笔记

    leetcode双人赛LeetCode 编号 题目 难度 题型 备注 Two Sum 简单 Add Two Numbers 中等 链结串列 重要 Longest Substring Without Repeating Characters 中等 字串 重要 Median of Two Sorted Arrays 困难 数学 ...

    leetcode分类-LeetCode:力码

    Palindromic Substring Interleaving String Triangle Distinct Subsequences Decode Ways Palindrome Partitioning II Maximal Rectangle ###Recursion N-Queens N-Queens II Balanced Binary Tree Binar

    leetcode2sumc-leetcode:JavaScript版本leetcode中文版代码

    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 ...

    leetcode题库-LeetCode:力码

    Palindromic Substring.cpp 7 整数反转 Reverse Integer.cpp 9 回文数 Palindrome Number.cpp 12 整数转罗马数字 Integer to Roman.cpp 13 罗马数字转整数 Roman to Integer.cpp 15 三数之和 3Sum.cpp 最接近的三数...

    leetcode中文版-LeetCode:LeetcodeC++/Java

    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答案-leetcode:leetcode问题解决方案

    leetcode ...Palindromic Substring Medium com.bcat.algorithms.medium.LongestPalindromSol 6 ZigZag Conversion Medium com.bcat.algorithms.medium.ZigZagConversionSol 7 Reverse Integer Easy ...

    javalruleetcode-Leetcode:力码解决方案

    java lru leetcode Leetcode-Java Use Java to solve Leetcode&JianZhiOffer ...Palindromic Substring (最长回文子串) Medium Dynamic Programming 7 Reverse Integer (整数反转) Easy Math 8 String to Integer (ato

    leetcode答案-LeetCode:我的力扣解决方案

    Substring: Learning "Manacher" algorithm. tips:substr(start_position,lens) 6. ZigZag Conversion: Find the Regulation. 11. Container With Most Water 问题简述:给出一个list a,找到一组i,j使得**min(a[i],a...

    leetcode答案-leetcode:leetcode

    leetcode 答案 leet code 这是我的leetcode答案,语言主要是用python。很多算法不是最优,甚至很槽糕,有空就会优化 目前完成了: Two Sum Add ...Palindromic Substring Regular Expression Matching

    leetcodepython001-leetcode:https://leetcode.com/的解决方案

    leetcode Python 001 力码 ├── Algorithms │  ├── cpp │  │  ├── 001 - Two Sum.cpp │  │  ├── 002 - Add Two Numbers.cpp │  │  ├── 003 - Longest Substring Without Repeating ...

Global site tag (gtag.js) - Google Analytics