1. 数据结构

  • 24.6.30 update

1.1. 用数组实现栈

/// 用数组实现栈
class Stack {
    var stack: [AnyObject]
    var isEmpty: Bool { stack.isEmpty }
    var peek: AnyObject? { stack.last }

    init() {
        stack = [AnyObject]()
    }

    func push(object: AnyObject) {
        stack.append(object)
    }

    func pop() -> AnyObject? {
        if (!isEmpty) {
            return stack.removeLast()
        } else {
            return nil
        }
    }
}

1.2. 字典和集合

给出一个整型数组和一个目标值,判断数组中是否有两个数之和等于目标值。

func twoSum(nums: [Int], _ target: Int) -> Bool {
    var set = Set<Int>()
    for num in nums {
        if set.contains(target - num) {
            return true
        }
        set.insert(num)
    }
    return false
}

给定一个整型数组中有且仅有两个数之和等于目标值,求这两个数在数组中的序列号。

func twoSum2(nums: [Int], _ target: Int) -> [Int] {
    var dict = [Int: Int]()
    for (i, num) in nums.enumerated() {
        if let lastIndex = dict[target - num] {
            return [lastIndex, i]
        } else {
            dict[num] = i
        }
    }
    fatalError("No valid output")
}

1.3. 字符串

给出一个字符串,要求将其按照单词顺序进行反转。比如,如果是“the sky is blue”,那么反转后的结果是“blue is sky the”。

fileprivate func _swap<T>(_ chars: inout [T], _ p: Int, _ q: Int) {
    (chars[p], chars[q]) = (chars[q], chars[p])
}

fileprivate func _reverse<T>(_ chars: inout [T], _ start: Int, _ end: Int) {
    var start = start, end = end
    while start < end {
        _swap(&chars, start, end)
        start += 1
        end -= 1
    }
}

func reverseWords(s: String?) -> String? {
    guard let s = s else { return nil }
    var chars = Array(s), start = 0
    _reverse(&chars, 0, chars.count - 1)
    for i in 0 ..< chars.count {
        if i == chars.count - 1 || chars[i+1] == " " {
            _reverse(&chars, start, i)
            start = i + 2
        }
    }
    return String(chars)
}

1.4. 链表

给出一个链表和一个值x,要求将链表中所有小于x的值放在左边,所有大于或等于x的值放到右边,并且原链表的结点顺序不能变。

func partition(_ head: ListNode?, _ x: Int) -> ListNode? {
    let prevDummy = ListNode(0), postDummy = ListNode(0)
    var prev = prevDummy, post = postDummy
    var node = head
    while node != nil {
        if node!.val < x {
            prev.next = node
            prev = node!
        } else {
            post.next = node
            post = node!
        }
        node = node!.next
    }
    post.next = nil
    prev.next = postDummy.next
    return prevDummy.next
}

删除链表中倒数第n个节点,例:1,2,3,4,5,n = 2,返回1,2,3,5。

func removeNthFromEnd(head: ListNode?, _ n: Int) -> ListNode? {
    guard let head = head else {
        return nil
    }
    let dumy = ListNode(0)
    dumy.next = head
    var prev: ListNode? = dumy
    var post: ListNode? = dumy
    for _ in 0 ..< n {
        if post == nil {
            break
        }
        post = post!.next
    }
    while post != nil && post!.next != nil {
        prev = prev!.next
        post = post!.next
    }
    prev!.next = prev!.next!.next
    return dumy.next
}

1.5. 栈和队列

/// 栈协议
protocol Stack {
    associatedtype Element
    var isEmpty: Bool { get }
    var size: Int { get }
    var peek: Element? { get }
    mutating func push(_ newElement: Element)
    mutating func pop() -> Element?
}
/// 栈实现
struct IntegerStack: Stack {
    typealias Element = Int
    private var stack = [Element]()
    var isEmpty: Bool { stack.isEmpty }
    var size: Int { stack.count }
    var peek: Int? { stack.last }

    mutating func push(_ newElement: Int) {
        stack.append(newElement)
    }

    mutating func pop() -> Int? {
        stack.popLast()
    }
}
/// 队列协议
protocol Queue {
    associatedtype Element
    var isEmpty: Bool { get }
    var size: Int { get }
    var peek: Element? { get }
    mutating func enqueue(_ newElement: Element)
    mutating func dequeue() -> Element?
}
/// 队列实现
struct IntegerQueue: Queue {
    typealias Element = Int
    private var left = [Element]()
    private var right = [Element]()
    var isEmpty: Bool { left.isEmpty && right.isEmpty }
    var size: Int { left.count + right.count }
    var peek: Int? { left.isEmpty ? right.first : left.last }
    mutating func enqueue(_ newElement: Int) {
        right.append(newElement)
    }
    mutating func dequeue() -> Int? {
        if left.isEmpty {
            left = right.reversed()
            right.removeAll()
        }
        return left.popLast()
    }
}

给出一个文件的绝对路径,要求将其简化。举个例子,路径是“/home/”,简化后为“/home”;路径是“/a/./b/../../c”,简化后为“/c”。

func simplifyPath(path: String) -> String {
    /// 用数组来实现栈的功能
    var pathStack = [String]()
    /// 拆分原路径
    let paths = path.components(separatedBy: "/")
    for path in paths {
        /// 对于“.”我们直接跳过
        guard path != "." else { continue }
        /// 对于“..”使用pop操作
        if path == ".." {
            if (pathStack.count > 0) {
                pathStack.removeLast()
            }
        /// 对于空数组的特殊情况
        } else if path != "" {
            pathStack.append(path)
        }
    }
    /// 将栈中的内容转化为优化后的新路径
    let res = pathStack.reduce("") { total, dir in "\(total)/\(dir)" }
    /// 注意空路径的结果是“/”
    return res.isEmpty ? "/" : res
}

用栈实现队列

/// 用数组实现栈
class Stack {
    var stack: [AnyObject]
    var isEmpty: Bool { stack.isEmpty }
    var peek: AnyObject? { stack.last }
    var size: Int { stack.count }

    init() {
        stack = [AnyObject]()
    }

    func push(object: AnyObject) {
        stack.append(object)
    }

    func pop() -> AnyObject? {
        if (!isEmpty) {
            return stack.removeLast()
        } else {
            return nil
        }
    }
}

/// 用栈实现队列
struct MyQueue {
    var stackA: Stack
    var stackB: Stack

    var isEmpty: Bool {
        stackA.isEmpty && stackB.isEmpty
    }

    var peek: Any? {
        shift()
        return stackB.peek
    }

    var size: Int {
        stackA.size + stackB.size
    }

    init() {
        stackA = Stack()
        stackB = Stack()
    }

    fileprivate func shift() {
        if stackB.isEmpty {
            while !stackA.isEmpty {
                stackB.push(object: stackA.pop()!)
            }
        }
    }

    func enqueue(object: AnyObject) {
        stackA.push(object: object)
    }

    func dequeue() -> AnyObject? {
        shift()
        return stackB.pop()
    }
}

用队列实现栈

struct Queue {
    private var left = [AnyObject]()
    private var right = [AnyObject]()
    var isEmpty: Bool { left.isEmpty && right.isEmpty }
    var size: Int { left.count + right.count }
    var peek: AnyObject? { left.isEmpty ? right.first : left.last }
    mutating func enqueue(_ newElement: AnyObject) {
        right.append(newElement)
    }
    mutating func dequeue() -> AnyObject? {
        if left.isEmpty {
            left = right.reversed()
            right.removeAll()
        }
        return left.popLast()
    }
}

/// 用队列实现栈
class MyStack {
    var queueA: Queue
    var queueB: Queue

    init() {
        queueA = Queue()
        queueB = Queue()
    }

    var isEmpty: Bool {
        queueA.isEmpty && queueB.isEmpty
    }

    var peek: AnyObject? {
        shift()
        let peekObj = queueA.peek
        queueB.enqueue(queueA.dequeue()!)
        swap()
        return peekObj
    }

    var size: Int {
        queueA.size
    }

    func push(object: AnyObject) {
        queueA.enqueue(object)
    }

    func pop() -> AnyObject? {
        shift()
        let popObject = queueA.dequeue()
        swap()
        return popObject
    }

    private func shift() {
        while queueA.size != 1 {
            queueB.enqueue(queueA.dequeue()!)
        }
    }

    private func swap() {
        (queueA, queueB) = (queueB, queueA)
    }
}

1.6. 二叉树

/// 节点
class TreeNode {
    var val: Int
    var left: TreeNode?
    var right: TreeNode?
    init(_ val: Int) {
        self.val = val
    }
}

/// 计算树的深度
func maxDepth(root: TreeNode?) -> Int {
    guard let root = root else { return 0 }
    return max(maxDepth(root: root.left), maxDepth(root: root.right)) + 1
}

/// 判断一个二叉树是否为二叉查找树
func isValidBST(root: TreeNode?) -> Bool {
    _helper(node: root, nil, nil)
}

private func _helper(node: TreeNode?, _ min: Int?, _ max: Int?) -> Bool {
    guard let node = node else { return true }
    /// 所有右子树的值都必须大于根节点的值
    if let min = min, node.val <= min {
        return false
    }
    /// 所有左子树的值都必须小于根节点的值
    if let max = max, node.val >= max {
        return false
    }
    return _helper(node: node.left, min, node.val) && _helper(node: node.right, node.val, max)
}

/// 用栈实现的前序遍历
func preorderTraversal(root: TreeNode?) -> [Int] {
    var res = [Int]()
    var stack = [TreeNode]()
    var node = root

    while !stack.isEmpty || node != nil {
        if node != nil {
            res.append(node!.val)
            stack.append(node!)
            node = node!.left
        } else {
            node = stack.removeLast().right
        }
    }
    return res
}

results matching ""

    No results matching ""