如何在Swift中指定和展开可选阵列对象?
我正在尝试使用迭代方法在Swift中反转二叉树。基本上,我只是在每个节点之间循环,并将其放入堆栈数组中。此数组应该是可选节点的数组。这是我的密码:如何在Swift中指定和展开可选阵列对象?,swift,binary-tree,optional,Swift,Binary Tree,Optional,我正在尝试使用迭代方法在Swift中反转二叉树。基本上,我只是在每个节点之间循环,并将其放入堆栈数组中。此数组应该是可选节点的数组。这是我的密码: func invertTree(_ root: TreeNode?) -> TreeNode? { if root != nil { stack.append(root) } else { return root } var
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
}
我得到了各种各样的可选错误。特别是,当我设置:
var tempLeft : TreeNode? = stack.last!.left
我不知道为什么它会说“可选类型TreeNode的值?必须展开才能引用solution.swift中展开的基类型“TreeNode”的成员“left”
我不明白为什么它告诉我打开可选的,而我已经在强制打开它。我不想打开.left节点,因为我想在堆栈中包含nils,以便迭代工作
任何帮助都将不胜感激
stack.last
是一个双重可选的TreeNode:TreeNode???
您可以使用如下可选链接:
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)
}
}
或者避免戏剧化,使用模式匹配:
if case let node?? = stack.last {
let tempLeft = node.left
node.left = node.right
node.right = tempLeft
...
除此之外,您的代码似乎还有其他方面需要改进。例如,在声明之前使用
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
}
}
将条件
if stack.last==nil{
更改为let last=stack.last{
(并交换if和else逻辑)以获得更快速的方法,然后使用last
变量而不需要任何展开。为什么堆栈需要是[TreeNode?]
而不仅仅是[TreeNode]
?非常感谢!我想给你投票,但我只有14个因果报应,所以它不会影响评级!但我想知道你是否可以解释第一个guard语句。如果我不使用该guard语句,而是使用guard root!=nil,我会得到一个错误。将根初始化为自身会打开它吗?不客气!如果这个答案解决了问题,请回答在代码中,您可以通过单击复选标记来编码并接受它。享受编码!guard let root=root else{return nil}
使用可选绑定,如果root
不是nil
,则初始化一个新变量,该变量恰好与root
同名,您可以将其称为r
或任何您觉得正常的名称。在代码的其余部分,您将引用此新变量,而不是初始的root
清楚,我将编辑答案。