链表是通过“指针”将一组零散的内存块串联使用,内存块陈伟链表的结点,没个链表的结点除了存储数据,还会使用后续指针next记录链上的下一个结点。
链表的第一个结点叫作头结点,最后一个结点叫作尾结点,头结点记录链表的基地址,而尾结点指向一个空地址NULL。
回文串是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。
判断是否是回文字符串的步骤:
1.创建一个结点类(包含存储的数据和next指针):
class ListNode: NSObject {
var value:Any?
var next:ListNode?
init(value:Any?) {
self.value = value
}
}
2.将一个字符串转换称为一个单链表:
class LinkedList: NSObject {
var linkedList:ListNode?
// 初始化字符串为单链表
init(value:String?) {
if value == nil || value?.count == 0 {
return
}
let array = Array(value!)
for tempValue in array.reversed() {
if linkedList == nil {
linkedList = ListNode.init(value: tempValue)
linkedList?.next = nil
} else {
let tempModel = ListNode.init(value: tempValue)
tempModel.next = linkedList;
linkedList = tempModel;
}
}
}
}
3.判断一个单链表存储的字符串是否是回文:
// “回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。
func isPalindrome(head:ListNode?) -> Bool {
if head == nil || head?.next == nil {
return true
}
var prev : ListNode? = nil
var slow : ListNode? = head
var fast : ListNode? = head
// 处理前面半截字符串的反转 和后半截字符串的截取
while fast != nil && fast?.next != nil {
fast = fast?.next?.next ?? nil
let next = slow?.next
slow?.next = prev
prev = slow
slow = next
}
//当为奇数位字符串的时候fast不为空 说明后半截多了一个中间的字符 所以需要等于next
if fast != nil {
slow = slow?.next
}
// 比较字符串是否一致
while slow != nil {
if (slow?.value as! Character) != (prev?.value as! Character) {
return false
}
slow = slow?.next
prev = prev?.next
}
return true
}
空间复杂度为O(1),时间复杂度为O(n)
参考java单链表存储的回文串