[Leetcode学习-c++&java]Longest Palindromic Substring

46 篇文章 0 订阅
这篇博客讨论了如何有效地解决LeetCode上的《最长回文子串》问题。作者提出了两种策略,一种是针对奇数长度和偶数长度的回文串,另一种是通过排除重复字符来优化比较次数。提供的Java和C++代码实现了这两种方法,并展示了如何在字符串中找到最长的回文子串。
摘要由CSDN通过智能技术生成

问题:

难度:medium

说明:

给出一个字符串,找出最长回文子串,子串是字符串集合连续的子集。

题目连接:https://leetcode.com/problems/longest-palindromic-substring/

输入范围:

  • 1 <= s.length <= 1000
  • s consist of only digits and English letters (lower-case and/or upper-case),

输入案例:

Example 1:
Input: s = "babad"
Output: "bab"
Note: "aba" is also a valid answer.

Example 2:
Input: s = "cbbd"
Output: "bb"

Example 3:
Input: s = "a"
Output: "a"

Example 4:
Input: s = "ac"
Output: "a"

我的代码:

幸好 1000 以内的长度输入,所以不用怕暴力暴死。

一般就两种情况:

1、奇数   bab 夹在中间的回文字符串是一个字母 a

2、偶数 baab 夹在中间的是 两个 a

然后就是遍历数组,每走一步都判断奇数偶数回文,不过有个方法更好就是直接每走一步,排除掉后续重复的字符。

str = "baab" 假设我走到 str[1] 这个地方,我进行排除重复,如果是 baab 我排除掉 str[2] 再进行回文判断,这样子就少了一次比较,如果是奇数 bab,也不会受影响,因此重复字符越多,效率越高。

Java:

class Solution {
    public String longestPalindrome(String s) {
        char[] chs = s.toCharArray();
        int len = chs.length, cur = 0, max = 0, left = 0;
        while(cur < len) {
            int tcur = cur, tpre = cur;
            while(tcur + 1 < len && chs[tcur] == chs[tcur + 1]) tcur ++; // 排除掉重复
            cur = tcur == cur ? cur + 1 : tcur + 1;
            while(tpre >= 0 && tcur < len && chs[tcur] == chs[tpre]) {// 再进行回文比较
                tcur ++; tpre --;
            }
            int temp = tcur - tpre - 1;
            if(temp > max) { // 获取最长
                max = temp; left = tpre + 1;
            }
        }
        return s.substring(left, left + max); // 省了个 right
    }
}

C++:

class Solution {
public:
    string longestPalindrome(string s) {
        int len = s.length(), max = 0, cur = 0, left = 0;
        while(cur < len) {
            int tcur = cur, tpre = cur;
            while(tcur + 1 < len && s[tcur] == s[tcur + 1]) tcur ++;
            cur = tcur == cur ? cur + 1 : tcur + 1;
            while(tpre >= 0 && tcur < len && s[tpre] == s[tcur]) {
                tpre --; tcur ++;
            }
            int temp = tcur - tpre - 1;
            if(temp > max) {
                max = temp; left = tpre + 1;
            }
        }
        return s.substr(left, max); // c++是从 i 开始,剪多少个字符
    }
};

如果不排除重复,用奇数偶数做法的话,是这样

Java:

    public String longestPalindrome(String s) {
        char[] chs = s.toCharArray();
        int len = chs.length, cur = 1, max = 0, maxLeft = 0, maxRight = 0;
        for(;cur < len;cur ++) {
            if(chs[cur - 1] == chs[cur]) { // 偶数
                int tpre = cur - 1, tcur = cur;
                while(tpre >= 0 && tcur < len && chs[tpre] == chs[tcur]) {
                    tpre --; tcur ++;
                }
                int temp = tcur - tpre - 1;
                if(temp > max) {
                    maxLeft = tpre + 1; maxRight = tcur - 1; max = temp;
                }
            }
            if(cur + 1 < len && chs[cur + 1] == chs[cur - 1]) { // 奇数
                int tpre = cur - 1, tcur = cur + 1;
                while(tpre >= 0 && tcur < len && chs[tpre] == chs[tcur]) {
                    tpre --; tcur ++;
                }
                int temp = tcur - tpre - 1;
                if(temp > max) {
                    maxLeft = tpre + 1; maxRight = tcur - 1; max = temp;
                }
            }
        }
        return s.substring(maxLeft, maxRight + 1);
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值