Swift ~ 链表小结

2019-02-14  本文已影响22人  派大星的博客

1、链表数据结构

public class ListNode {
    public var val: Int
    public var next: ListNode?
    public init(_ val: Int) {
        self.val = val
        self.next = nil
    }
}

2、 根据给定数组生成一个链表

    func createList(_ array: [Int]) -> ListNode? {
        let head: ListNode? = ListNode(-1)
        var ref: ListNode? = head
        
        for item in array {
            let listItem = ListNode(item)
            ref?.next = listItem
            ref = ref?.next
        }
        return head?.next
    }

3、插入节点

  // 插入尾节点
    func addToTail(_ head: ListNode?, val: Int) -> ListNode? {
        let item = ListNode(val)
        
        if head == nil {
            return item
        } else {
            var ref = head
            while ref?.next != nil {
                ref = ref?.next
            }
            ref?.next = item
            return head
        }
    }

     // 插入头节点
    func addToFront(_ head: ListNode?, val: Int) -> ListNode? {
        let item = ListNode(val)
        item.next = head
        return item
    }

4、删除第一个val节点

    // 因为头结点有可能被删除,此时我们用一个headPre指向当前的头节点,进行遍历。
    func removeNode(_ head: ListNode?, val: Int) -> ListNode? {
        let headPre : ListNode? = ListNode(-1)
        headPre?.next = head
        var ref = headPre
        while (ref?.next != nil) {
            if (ref?.next?.val == val) {
                ref?.next = ref?.next?.next
                break
            }
            ref = ref?.next
        }
        return headPre?.next   
 }

5、删除所有val节点

    // Remove all elements from a linked list of integers that have value val.
    func removeElements(_ head: ListNode?, _ val: Int) -> ListNode? {
        let headPre : ListNode? = ListNode(val)
        headPre?.next = head
        var ref = headPre
        while (ref?.next != nil) {
            if (ref?.next?.val == val) {
                ref?.next = ref?.next?.next
            } else {
                ref = ref?.next
            }
        }
        
        return headPre?.next
    }
    
    // 官方优秀实现 
    func removeElements2(_ head: ListNode?, _ val: Int) -> ListNode? {
        guard head != nil else { return nil }
        
        var head = head
        while head != nil, head!.val == val {
            head = head?.next
        }
        
        var prev = head
        var current = head?.next
        
        while let curr = current {
            if curr.val == val {
                prev?.next = curr.next
                current = curr.next
                continue
            }
            prev = curr
            current = curr.next
        }
        
        return head
    }

6、找到中间节点

    func middleNode(_ head: ListNode?) -> ListNode? {
        var p1 = head
        var p2 = head
        while p2?.next != nil {
            p1 = p1?.next
            p2 = p2?.next?.next
        }
        return p1
    }
    

7、反转链表

我的简易理解:逐个遍历原链表节点,利用插入头指针的方法生成逆序的新链表。

    func reverseList(_ head: ListNode?) -> ListNode? {
        var rList : ListNode? = nil
        var lList = head
        var tmp : ListNode? = nil
        while lList != nil {
            tmp = lList
            lList = lList?.next
            tmp?.next = rList
            rList = tmp
        }
        return rList
    }
    // 官方优秀递归实现
    func reverseListRecursively(_ head: ListNode?) -> ListNode? {
        if let head = head {
            if let next = head.next {
                let newHead = reverseList(next)
                next.next = head
                head.next = nil
                return newHead
            }
        }
        return head
    }

8、合并两个有序链表

    func mergeTwoLists(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
        let headPre : ListNode? = ListNode(-1)
        var ref = headPre
        var l = l1
        var r = l2
        while (l != nil && r != nil) {
            if l!.val <= r!.val {
                ref?.next = l
                ref = ref?.next
                l = l?.next
            } else {
                ref?.next = r
                ref = ref?.next
                r = r?.next
            }
        }
        if l == nil {
            ref?.next = r
        } else {
            ref?.next = l
        }
        return headPre?.next
    }
    
    // 官方优秀递归实现
    func mergeTwoListsRecursively(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
        if l1 == nil {
            return l2
        }
        
        if l2 == nil{
            return l1
        }
        
        if let first = l1, let second = l2{
            if first.val < second.val{
                first.next = mergeTwoLists(first.next, second)
                return first
            } else {
                second.next = mergeTwoLists(first, second.next)
                return second
            }
        }
        return nil
    }

9、请检查一个链表是否为回文链表

进阶:你能在 O(n) 的时间和 O(1) 的额外空间中做到吗?

思路:链表用到了快慢指针,快指针每次跳两下,慢指针每次跳一下,这样快指针到终点的时候慢指针刚好一般,然后反转后半部分链表进行对比。 该方法时间复杂度O(n)、空间复杂度O(1).

    func isPalindrome(_ head: ListNode?) -> Bool {
        let middle = self.middleNode(head)
        let reverse = self.reverseList(middle)
        var r = reverse
        var l = head
        while r != nil {
            if r?.val != l?.val {
                return false
            }
            r = r?.next
            l = l?.next
        }
        return true
    }

10、给定一个链表,去除重复的元素,使每个元素最多出现一次

Remove Duplicates from Sorted List
给定一个链表,去除重复的元素,使每个元素最多出现一次。
例如:给定 1->1->2, 返回 1->2.
给定 1->1->2->3->3, 返回 1->2->3.

    func deleteDuplicate(_ head: ListNode?) -> ListNode? {
        var tmp = head
        while tmp != nil {
            if tmp?.next?.val == tmp?.val {
                tmp?.next = tmp?.next?.next
            } else {
                tmp = tmp?.next
            }
        }
        return head
    }

11、给定一个链表,要求删除重复的元素,只保留单独的元素

Remove Duplicates from Sorted List II
给定一个链表,要求删除重复的元素,只保留单独的元素。
例如:给定 1->2->3->3->4->4->5, 返回 1->2->5.
给定 1->1->1->2->3, 返回 2->3.

便利提示:因为头结点有可能被删除,此时我们用一个headPre指向当前的头节点,进行遍历。

 func deleteDuplicates(_ head: ListNode?) -> ListNode? {
        let headPre : ListNode? = ListNode(-1)
        headPre?.next = head
        var ref = headPre
        while (ref?.next != nil && ref?.next?.next != nil){
            if (ref?.next?.val == ref?.next?.next?.val) {
                let value = ref?.next?.val
                while(ref?.next != nil && ref?.next?.val == value) {
                    ref?.next = ref?.next?.next
                }
            } else {
                ref = ref?.next
            }
        }
        return headPre?.next
    }
    
    // 官方优秀实现
    func deleteDuplicatesLeetcode(_ head: ListNode?) -> ListNode? {
        if head == nil || head?.next == nil { return head }
        let dummy = ListNode(0)
        var node: ListNode? = dummy
        var slow = head
        var fast = head?.next
        var dupli = false
        while fast != nil {
            if fast!.val == slow!.val {
                dupli = true
            } else {
                if !dupli {
                    node?.next = slow
                    node = slow
                }
                dupli = false
            }
            slow = fast
            fast = fast?.next
        }
        if !dupli {
            node?.next = slow
            node = slow
        }
        node?.next = nil
        return dummy.next
    }
上一篇下一篇

猜你喜欢

热点阅读