【问题标题】:Optional node in linked list链表中的可选节点
【发布时间】:2018-03-08 04:56:04
【问题描述】:

我正在练习 Swift 语言。 我正在用 xcode 中的 Playground 解决 Leetcode 问题。

我对链表中的 assining 和绑定可选值感到困惑。

这是我的代码。

     // Definition for singly-linked list.
      public class ListNode {
          public var val: Int
          public var next: ListNode?
          public init(_ val: Int) {
              self.val = val
              self.next = nil
          }
      }

    var l1 = ListNode(2)
    l1.next  = ListNode(4)
    //first error: here I have an error that editor explains "Value of optional type 'ListNode?' not unwrapped; did you mean to use '!' or '?'?"
    l1.next.next = ListNode(3)




    //second warning : editors explains that Comparing non-optional value of type 'ListNode' to nil always returns true
    while l1 != nil{
        print(l1.val)
        if let nextNode = l1.next{
            l1 = nextNode
        }
    }

对于第一个错误,如果我输入 !对于展开,它仍然显示错误。

l1.next!.next! = ListNode(3) 或 l1.next.next! = ListNode(3)

我认为我可以展开,因为我确信我为第二个节点放置了正确的节点。

我也试过了

    var l1 = ListNode(2)
    l1.next?  = ListNode(4)
    l1.next!.next? = ListNode(3)

那么我会得到

执行被中断,原因:EXC_BAD_INSTRUCTION (代码=EXC_I386_INVOP,子代码=0x0)。

请让我理解可选表达式的正确使用。

【问题讨论】:

  • 你需要在init函数中为“next”赋值
  • 我认为下一个将是具有 nil 值的 init。不是吗?
  • @UdayBabariya 这不是原因

标签: swift linked-list optional


【解决方案1】:

这里出错了

//first error: here I have an error that editor explains "Value of optional type 'ListNode?' not unwrapped; did you mean to use '!' or '?'?"
l1.next.next = ListNode(3)

因为l1.nextOptional 类型的ListNode,所以它有可能是nil。所以它不允许你分配.next 两次而不打开它。

l1.next?.next = ListNode(3)

第二种情况

while l1 != nil{
        print(l1.val)
        if let nextNode = l1.next{
            l1 = nextNode
        }
    }

EDIT2

var node  = l1.next 

while node != nil {
   print (node.value)
  node = node.next
}

这里l1 不是可选的。 l1.next 是可选的,所以你应该

使用while l1.next != nil 循环下一个元素。否则这里不需要循环

编辑

为什么l1.next!.next! = ListNode(3)会造成崩溃?

首先不要强行解开任何可选值。

你在这里做的是首先next 很好。您可以获得下一个对象,但对于第二个 next,您将在其中分配新值 ListNode(3) 仍然为零,所以您的应用程序正在抛出错误。

希望对你有帮助

【讨论】:

  • 对于第二个问题,日志只显示2和4。我想知道可选绑定的正确表达式。 ——
  • @JanghyupLee 你也应该保留 Head 节点。在一些全球var
【解决方案2】:

根据Apple's documentation

可选链是查询和调用属性的过程, 方法,以及当前可能为 nil 的可选项上的下标。如果 可选项包含一个值、属性、方法或下标调用 成功;如果可选项为 nil,则属性、方法或下标 调用返回零。多个查询可以链接在一起,并且 如果链中的任何链接为零,则整个链都会优雅地失败。

您可以按如下方式更新您的代码

// Definition for singly-linked list.
public class ListNode {
    public var val: Int
    public var next: ListNode?
    public init(_ val: Int) {
        self.val = val
        self.next = nil
    }
}

var l1 = ListNode(2)
l1.next  = ListNode(4)
l1.next?.next = ListNode(3) 
//By using the '?' operator, you're essentially saying that if l1's next is nil,
//do nothing; otherwise, assign ListNode(3) to it

对于您的第二个问题,这里会出现警告,因为您正在检查 l1(non-optional) 与 nil 的对比,在您的情况下这将始终返回 true。你想要某种递归。试试下面的

func printValuesFrom(_ node: ListNode) {
    print(node.val)
    if let next = node.next {
        printValuesFromNode(next)
    }
}

printValuesFrom(l1)

【讨论】:

  • 对于第二个问题,日志只显示2和4。我想知道可选绑定的正确表达式。
【解决方案3】:

试试这个方法……

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

    var l1 = ListNode(1,nil)

    var l2 = ListNode(2,nil)
    l1.next  = l2 

  // or l1.next = ListNode(2,nil)

【讨论】:

    猜你喜欢
    • 2021-10-08
    • 1970-01-01
    • 1970-01-01
    • 2019-10-03
    • 1970-01-01
    • 2015-04-03
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多