简体   繁体   English

如何在Swift中分配和解包可选数组对象?

[英]How do you assign and unwrap an optional array object in Swift?

I'm trying to invert a binary tree in Swift using the iterative approach. 我正在尝试使用迭代方法在Swift中反转二叉树。 Essentially I just keep looping through each node, and putting it into a stack array. 本质上,我只是不断遍历每个节点,并将其放入堆栈数组中。 This array should be an array of optional nodes. 该数组应该是可选节点的数组。 Here is my code: 这是我的代码:

 func invertTree(_ root: TreeNode?) -> TreeNode? { 
        if root != nil {
            stack.append(root) 
        } else {
            return root
        }

        var stack = [TreeNode?]()
        while stack.count > 0 {
            if stack.last == nil {
                stack.removeLast()
            } else {

                var tempLeft : TreeNode? = stack.last!.left
                stack.last!.left = stack.last!.right
                stack.last!.right = tempLeft

                if stack.last!.left != nil {
                    stack.append(stack.last!.left)
                }

                if stack.last.right != nil {
                    stack.append(stack.last!.right)
                }
            }
        }
        return root
}

I'm getting all sorts of optional errors. 我遇到各种各样的可选错误。 In particular, when I set: 特别是当我设置时:

var tempLeft : TreeNode? = stack.last!.left

I'm not sure why it says "value of optional type TreeNode? must be unwrapped to refer to member 'left' of unwrapped base type 'TreeNode' in solution.swift" 我不确定为什么它说“必须将可选类型TreeNode的值解包,以引用solution.swift中解包基本类型'TreeNode'的成员'left'”

I don't understand why it's telling me to unwrap the optional, when I'm already force unwrapping it. 我不明白为什么当我已经强制展开可选内容时,它告诉我取消可选内容。 I don't want to unwrap the .left node since I want to include nils in my stack for the iteration to work. 我不想解包.left节点,因为我想在堆栈中包含nil以使迭代正常进行。

Any help would be greatly appreciated. 任何帮助将不胜感激。

stack.last is a doubly optional TreeNode: TreeNode?? stack.last是一个双重可选的TreeNode: TreeNode?? .

You could use optional chaining like so: 您可以使用可选的链接,如下所示:

if stack.last == nil {
    stack.removeLast()
} else {
    stack.last
    var tempLeft : TreeNode? = stack.last!?.left
    stack.last!?.left = stack.last!?.right
    stack.last!?.right = tempLeft

    if stack.last!?.left != nil {
        stack.append(stack.last!?.left)
    }

    if stack.last??.right != nil {
        stack.append(stack.last!?.right)
    }
}

Or avoid the drama and use pattern matching: 或避免戏剧性并使用模式匹配:

if case let node?? = stack.last {
    let tempLeft = node.left
    node.left = node.right
    node.right = tempLeft

    ...

Other than that, it seems that there are other areas of your code that you need to tend to. 除此之外,似乎还需要处理代码的其他区域。 For example, using stack before its declaration. 例如,在声明之前使用stack


Alternative implementation 替代实施

Here is a solution that uses a stack: 这是使用堆栈的解决方案:

class Solution {
    func invertTree(_ root: TreeNode?) -> TreeNode? {

        guard let r = root else {
            return nil
        }

        var stack = [r]

        while let node = stack.last {
            let temp   = node.left
            node.left  = node.right
            node.right = temp

            stack.removeLast()

            if let left  = node.left  { stack.append(left)  }
            if let right = node.right { stack.append(right) }
        }

        return r
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM