题目描述
回文,英文palindrome,指一个顺着读和反过来读都一样的字符串,比如madam、我爱我,这样的短句在智力性、趣味性和艺术性上都颇有特色,中国历史上还有很多有趣的回文诗。
那么,我们的第一个问题就是:判断一个字串是否是回文?
分析与解法
使用两个指针,分别从两端扫描,直到指针相遇,如果中间出现不同字符,则直接返回 false,否则返回 true
package main
import "fmt"
func isPalindrome(runes []rune) bool {
left := 0
right := len(runes) - 1
for left < right {
if runes[left] != runes[right] {
return false
}
left ++
right --
}
return true
}
func main() {
runes := []rune("wew")
fmt.Println(isPalindrome(runes))
}
举一反三
1、判断一条单向链表是不是“回文”
分析:先逆置链表的后半段,然后分别从头和中间位置逐项比较,再恢复原链表
package main
import "fmt"
type Node struct {
Val int
Next *Node
}
// 递归反转链表(必备)
func reverse(head *Node) *Node {
if head != nil && head.Next != nil {
newHead := reverse(head.Next)
head.Next.Next = head
head.Next = nil
return newHead
}
return head
}
func isPalindrome(head *Node) bool {
rtn := true
if head == nil {
return rtn
}
// 快慢指针法,找到中间节点 slow
fast, slow := head, head
for fast.Next != nil && fast.Next.Next != nil {
fast = fast.Next.Next
slow = slow.Next
}
// rec 记住中间位置,以便恢复
rec := slow
// slow.Next 为后半部分开头,
p := slow.Next
// 分离前后链表
slow.Next = nil
// 反转后边链表
h2 := reverse(p)
// 判断是否回文
for p1, p2 := head, h2; p2 != nil; p1, p2 = p1.Next, p2.Next {
if p1.Val != p2.Val {
rtn = false
break
}
}
// 恢复链表
rec.Next = reverse(h2)
return rtn
}
func main() {
head := &Node{1, nil}
n1 := &Node{2, nil}
n2 := &Node{1, nil}
head.Next = n1
n1.Next = n2
fmt.Println(isPalindrome(head))
}
2、判断一个栈是不是“回文”,使用自定义栈
package main
import (
"container/list"
"fmt"
)
// 定义栈 Stack
type Stack struct {
list *list.List
}
func NewStack() *Stack {
list := list.New()
return &Stack{list}
}
func (stack *Stack) Push(value interface{}) {
stack.list.PushBack(value)
}
func (stack *Stack) Pop() interface{} {
e := stack.list.Back()
if e != nil {
stack.list.Remove(e)
return e.Value
}
return nil
}
func (stack *Stack) Peak() interface{} {
e := stack.list.Back()
if e != nil {
return e.Value
}
return nil
}
func (stack *Stack) Len() int {
return stack.list.Len()
}
func (stack *Stack) Empty() bool {
return stack.list.Len() == 0
}
func isPalindrome(str string) bool {
stack := NewStack()
for _, c := range str {
stack.Push(c)
}
for i := 0; i < len(str); i++ {
if stack.Pop().(int32) != int32(str[i]) {
return false
}
}
return true
}
func main() {
str := "abba"
fmt.Println(isPalindrome(str))
}