持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情
LeetCode 75 —— 409. 最长回文串
一、题目描述:
给定一个包含大写字母和小写字母的字符串 s ,返回 通过这些字母构造成的 最长的回文串 。
在构造过程中,请注意 区分大小写 。比如 "Aa" 不能当做一个回文字符串。
示例 1:
输入:s = "abccccdd" 输出:7 解释: 我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。
示例 2:
输入:s = "a" 输入:1
提示:
1 <= s.length <= 2000 s 只由小写 和/或 大写英文字母组成
来源:力扣(LeetCode) 链接:leetcode.cn/problems/lo… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、思路分析:
-
这道题考察了什么思想?你的思路是什么?
看到这道题目,要构成最长回文数,我想回文数就是除了中间一个字母可以为单,其他每对字母都可以放入回文串里面,于是我们计算每组字母的成对数,然后如果之和不等于字符串长度,就最长回文串长度加一即可,如果成对数之和等于字符串长度,我们就取字符串长度即可。
结果证明可行!
具体代码请看下文AC代码。
-
做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?
不是,刚开始虽然写思路的时候考虑了如果之和不等于字符串长度,就最长回文串长度加一即可,如果成对数之和等于字符串长度,我们就取字符串长度即可。但是写代码的时候还是没考虑,导致测试点为“bb”的时候,返回最长回文串长度为3,我们根据上面的思路,对代码进行简单修改,即通过全部测试用例!这启示我有时候边写代码边思考很容易考虑不周全,需要提前想好程序的编写思路。
-
有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?
大家的解法和我差不多,但是感觉下面这位大佬的解法更美观,更精简。
func longestPalindrome(s string) int { // 贪心算法 charCnt := make(map[byte]int) // 统计字符次数 for i:=0;i<len(s);i++ { charCnt[s[i]]++ } // 偶数数量字符不变,奇数字符数量如 3/2 *2 = 2,数量-1 count := 0 for _, cnt := range charCnt { count += cnt/2 * 2 } // 如果count数量未超过长度,count+1,实际让某个奇数数量的字符由count的偶数+1 // 仅满足有一个奇数字符数量 if count < len(s) { return count+1 } // 如果等于len说明本身就可以构成回文,因为字符全是偶数数量 return count } 作者:davis-wen12 链接:https://leetcode.cn/problems/longest-palindrome/solution/tan-xin-suan-fa-count-cnt2-2zui-hou-kan-kwz1o/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
三、AC 代码:
func longestPalindrome(s string) int { var byte_map = make(map[byte]int) for i:=0;i<len(s);i++ { if _,ok := byte_map[s[i]];!ok{ byte_map[s[i]] = 1 } else { byte_map[s[i]]++ } } //fmt.Println(byte_map) var length int = 0 for key,_ := range byte_map{ if(byte_map[key]>1 && byte_map[key] % 2 != 0){ length += byte_map[key] - 1 } else if(byte_map[key]>1 && byte_map[key] % 2 == 0){ length += byte_map[key] } } if length == len(s){ return length } return length+1 }
四、总结:
该题我们采用哈希表+贪心的方法,时间复杂度为O(N),空间复杂度为O(S)。
模板来源:
作者:掘金酱
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。