zoukankan      html  css  js  c++  java
  • LeetCode Golang 5. 最长回文子串

    5. 最长回文子串

    给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

    示例 1:

    输入: "babad"
    输出: "bab"
    注意: "aba" 也是一个有效答案。
    

    示例 2:

    输入: "cbbd"
    输出: "bb"

    暴力解法: 列出子串, 求出符合条件的子串存入map, 筛选出最大值存入

    func longestPalindrome(s string) string {
    	if s == "" {
    		return ""
    	}
    	if isPalindrome(s) {
    		return s
    	}
    
    	pdMap := make(map[string]int)
    	for i := 0; i < len(s); i++ {
    		for j:=len(s);j>i+1;j--{
    			tmp := s[i:j]
    			//fmt.Println(tmp)
    			if isPalindrome(tmp) {
    				pdMap[tmp] = len(tmp)
    			}
    		}
    	}
    	max := 0
    	rst := ""
    	for k,v := range pdMap {
    		if v > max {
    			max = v
    			rst = k
    		}
    	}
        if rst == "" {
    		return s[0:1]
    	}
    	return rst
    }
    
    func isPalindrome(s string) bool {
    	if len(s) < 1 {
    		return false
    	}
    	if len(s) == 2 && s[0]==s[1]{
    		return true
    	}
    	for i:=0;i<len(s)/2;i++{ // 3/2 = 1    4/2 = 2
    		if s[i] != s[len(s)-i-1] {
    			return false
    		}
    	}
    	return true
    }
    

      

    优化1: 因为题目只要求 最长, 所以只需要返回最长的就可以了, 引入map实际上浪费了空间

    package main
    
    import "fmt"
    
    //给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
    //
    //示例 1:
    //
    //输入: "babad"
    //输出: "bab"
    //注意: "aba" 也是一个有效答案。
    //示例 2:
    //
    //输入: "cbbd"
    //输出: "bb"
    
    func main() {
    	s := "abb"
    	fmt.Println(longestPalindrome(s))
    }
    
    func longestPalindrome(s string) string {
    	if s == "" {
    		return ""
    	}
    	if isPalindrome(s) || len(s) < 2 {
    		return s
    	}
    
    	max := 0
    	rst := ""
    	
    	for i := 0; i < len(s); i++ {
    		for j:=len(s);j>i+1;j--{
    			tmp := s[i:j]
    			//fmt.Println(tmp)
    			if isPalindrome(tmp) {
    				if max < len(tmp) {
    					max = len(tmp)
    					rst = tmp
    				}
    			}
    		}
    	}
    	
    	if rst == "" {
    		return s[0:1]
    	}
    	return rst
    }
    
    func isPalindrome(s string) bool {
    	if len(s) < 1 {
    		return false
    	}
    	if len(s) == 2 && s[0]==s[1]{
    		return true
    	}
    	for i:=0;i<len(s)/2;i++{ // 3/2 = 1    4/2 = 2
    		if s[i] != s[len(s)-i-1] {
    			return false
    		}
    	}
    	return true
    }
    

    大神解法:

    func longestPalindrome(s string) string {
         if len(s) < 2 { // 肯定是回文,直接返回
            return s
        }
    
        // 最长回文的首字符索引,和最长回文的长度
        begin, maxLen := 0, 1
    
        // 在 for 循环中
        // b 代表回文的**首**字符索引号,
        // e 代表回文的**尾**字符索引号,
        // i 代表回文`正中间段`首字符的索引号
        // 在每一次for循环中
        // 先从i开始,利用`正中间段`所有字符相同的特性,让b,e分别指向`正中间段`的首尾
        // 再从`正中间段`向两边扩张,让b,e分别指向此`正中间段`为中心的最长回文的首尾
        for i := 0; i < len(s); { // 以s[i]为`正中间段`首字符开始寻找最长回文。
            if len(s)-i <= maxLen/2 {
                // 因为i是回文`正中间段`首字符的索引号
                // 假设此时能找到的最长回文的长度为l, 则,l <= (len(s)-i)*2 - 1
                // 如果,len(s)-i <= maxLen/2 成立
                // 则,l <= maxLen - 1
                // 则,l < maxLen
                // 所以,无需再找下去了。
                break
            }
    
            b, e := i, i
            for e < len(s)-1 && s[e+1] == s[e] {
                e++
                // 循环结束后,s[b:e+1]是一串相同的字符串
            }
    
            // 下一个回文的`正中间段`的首字符只会是s[e+1]
            // 为下一次循环做准备
            i = e + 1
    
            for e < len(s)-1 && b > 0 && s[e+1] == s[b-1] {
                e++
                b--
                // 循环结束后,s[b:e+1]是这次能找到的最长回文。
            }
    
            newLen := e + 1 - b
            // 创新记录的话,就更新记录
            if newLen > maxLen {
                begin = b
                maxLen = newLen
            }
        }
    
        return s[begin : begin+maxLen]
    
    }
    

      

    这里还有一些算法, 由leetCode官方提供:

    https://leetcode-cn.com/problems/longest-palindromic-substring/solution/

  • 相关阅读:
    【翻译】ASP.NET Web API入门
    ASP.NET Web API 简介
    浅析利用MetaWeblog接口同步多个博客
    说说JSON和JSONP,也许你会豁然开朗
    说说JSON和JSONP,也许你会豁然开朗
    点击ListView 获取所选择行的数据
    Label 控件设置背景透明色
    C#遍历窗体所有控件或某类型所有控件 (转)
    使用Window 自带的控件 axWindowsMediaPlayer 制作播放器
    ASP.net 学习路线(详细)
  • 原文地址:https://www.cnblogs.com/gettolive/p/10191459.html
Copyright © 2011-2022 走看看