判断单链表存储的字符串是否是回文字符串

链表是通过“指针”将一组零散的内存块串联使用,内存块陈伟链表的结点,没个链表的结点除了存储数据,还会使用后续指针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单链表存储的回文串

你可能感兴趣的:(判断单链表存储的字符串是否是回文字符串)