博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Golang面试考题记录 ━━ 验证回文串,多种方法涉及双指针、strings、unicode和regexp
阅读量:4115 次
发布时间:2019-05-25

本文共 3072 字,大约阅读时间需要 10 分钟。

===问:

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

**说明:**本题中,我们将空字符串定义为有效的回文串。

示例 1:

输入: “A man, a plan, a canal: Panama”

输出: true

示例 2:

输入: “race a car”

输出: false

===答:

方法一:

执行用时 :500 ms, 击败了5.29% 的用户
内存消耗 :7.6 MB, 击败了25.00%的用户

通过循环,生成只留下英文和数字的正向字符串a、反向字符串b

ab进行比较是否一致
本方法执行效率极低~~

func isPalindrome1(s string) bool {
l := len(s) - 1 if l < 1 {
return true } s = strings.ToLower(s) a := "" b := "" for i := l; i >= 0; i-- {
if (s[i] >= 48 && s[i] <= 57) || (s[i] >= 97 && s[i] <= 122) {
a += string(s[i]) } if (s[l-i] >= 48 && s[l-i] <= 57) || (s[l-i] >= 97 && s[l-i] <= 122) {
b += string(s[l-i]) } } if a == b {
return true } return false}

方法二:

执行用时 :248 ms, 击败了5.29% 的用户
内存消耗 :8.3 MB, 击败了16.67%的用户

在方法一的基础上进化一下,遍历只留下英文和数字的逆向字符串a

原字符串s的字母和数字一一比对a,一旦出现不等就返回false
本方法内存占用比方法一增加,执行效率比方法一提升一倍

func isPalindrome2(s string) bool {
l := len(s) - 1 if l < 1 {
return true } s = strings.ToLower(s) a := "" for i := l; i >= 0; i-- {
if (s[i] >= 48 && s[i] <= 57) || (s[i] >= 97 && s[i] <= 122) {
a += string(s[i]) } } j := 0 for i := range s {
if (s[i] >= 48 && s[i] <= 57) || (s[i] >= 97 && s[i] <= 122) {
if a[j] != s[i] {
fmt.Println(a, s, string(a[j]), string(s[i])) return false } j++ } } return true}

方法三:

执行用时 :40 ms, 击败了10.10% 的用户
内存消耗 :8.5 MB, 击败了16.67%的用户

在方法二的基础上再进化一下,利用正则表达式留下英文和数字的切片t

循环次数只使用该切片t长度的一半,依次前后进行比对,一旦出现不等就返回false
本方法内存占用比方法二增加,执行效率比方法二提升五倍

func isPalindrome3(s string) bool {
if len(s) < 2 {
return true } s = strings.ToLower(s) re := regexp.MustCompile("\\w") t := re.FindAll([]byte(s), -1) l := len(t) for i := 0; i < l/2; i++ {
if t[i][0] != t[l-1-i][0] {
return false } } return true}

方法四:

执行用时 :32 ms/24 ms, 击败了10.74%/12.98% 的用户
内存消耗 :7.5 MB, 击败了25.00%的用户

方法三的基础上进一步简化,去掉了不必要的变量

本方法内存占用比方法三降低,执行效率比方法三提升一倍

func isPalindrome4(s string) bool {
t := regexp.MustCompile("\\w").FindAllString(strings.ToLower(s), -1) for i := 0; i < len(t)/2; i++ {
if t[i] != t[len(t)-1-i] {
return false } } return true}

方法五:

执行用时 :0 ms/4 ms, 击败了100.00%/68.11% 的用户
内存消耗 :2.7 MB, 击败了91.67%/75.00% 的用户

前面四种方法的执行情况和排名实在无法令人满意,因此本方法使用了双指针法。

遍历时双指针ij分别从字符串前后移动,并通过unicode的方法来判断当前字符是否为数字或字母,
如果不是数字和字母,则其对应的指针ij移动1并进入下一次循环。
如果数字和字母都符合要求,但值不相同,则返回false
本方法内存占用比方法四降低近2倍,执行效率比方法四提升五倍以上

func isPalindrome5(s string) bool {
if len(s) < 2 {
return true } i, j := 0, len(s)-1 for i < j {
if !unicode.IsDigit(rune(s[i])) && !unicode.IsLetter(rune(s[i])) {
i++ continue } if !unicode.IsDigit(rune(s[j])) && !unicode.IsLetter(rune(s[j])) {
j-- continue } if unicode.ToLower(rune(s[i])) != unicode.ToLower(rune(s[j])) {
return false } i++ j-- } return true}

===解:

什么是回文串?

“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。

参考:《》

字符串 strings.

方法一、二、三、四中使用strings.ToLower()来将字符串字母改为小写

其余的包含、替换、拼接、分割等等方法请

参考:《》

正则 regexp.

方法中使用正则过滤了字符串,只留英文和数字

[a-zA-Z0-9]遗漏 ´,所以方法中使用了\\w

参考:《》

unicode.

方法五中利用unicode的方法来判断字符是否为英文或数字,强制转换小写,执行效率非常高,加入了这么多的条件语句,竟然执行效率没有降低。

注意:使用时需要利用rune()来强制转换类型为rune,即int32

参考:《》

rune

关于几个类型的关系可以参考我之前写的日志。

参考:《》

转载地址:http://ntkpi.baihongyu.com/

你可能感兴趣的文章
element ui 弹窗在IE11中关闭时闪现问题修复
查看>>
vue 遍历对象并动态绑定在下拉列表中
查看>>
Vue动态生成el-checkbox点击无法选中的解决方法
查看>>
python __future__
查看>>
MySQL Tricks1
查看>>
python 变量作用域问题(经典坑)
查看>>
pytorch
查看>>
pytorch(二)
查看>>
pytorch(三)
查看>>
pytorch(四)
查看>>
pytorch(5)
查看>>
pytorch(6)
查看>>
ubuntu相关
查看>>
C++ 调用json
查看>>
nano中设置脚本开机自启动
查看>>
动态库调动态库
查看>>
Kubernetes集群搭建之CNI-Flanneld部署篇
查看>>
k8s web终端连接工具
查看>>
手绘VS码绘(一):静态图绘制(码绘使用P5.js)
查看>>
手绘VS码绘(二):动态图绘制(码绘使用Processing)
查看>>