【问题标题】:LinkedList why do we have to create the dummy here?LinkedList 为什么我们要在这里创建 dummy 呢?
【发布时间】:2017-01-14 20:38:21
【问题描述】:

我是解决与数据结构相关的算法的新手,我不确定遇到问题的以下代码:

public ListNode swapPairs(ListNode head) {
    ListNode dummy = new ListNode(0);
    dummy.next = head;

    head = dummy;
    while (head.next != null && head.next.next != null) {
        ListNode n1 = head.next, n2 = head.next.next;

        head.next = n2;
        n1.next = n2.next;
        n2.next = n1;                   
        head = n1;
    }
    return dummy.next;
}

为什么我们必须在这里创建虚拟对象?

如果您能帮助我解决这个问题,那将是非常有帮助的。当您必须对链表执行某些操作时,我观察到了类似的步骤。

【问题讨论】:

  • 这个函数是从哪里来的? swapPairs() 应该做什么有定义吗?在不知道预期行为是什么的情况下,我们无法告诉您为什么它以某种方式编写......
  • 嗨,这是问题。请看一看。谢谢。给定一个链表,交换每两个相邻节点并返回它的头部。例如,给定 1->2->3->4,您应该将列表返回为 2->1->4->3。你的算法应该只使用常数空间。您不能修改列表中的值,只能更改节点本身。爪哇
  • 它使循环内的代码更简单。否则每次更改节点时,您都​​必须担心它是否是头部。
  • 感谢您的评论。现在把事情说清楚了。当我们必须对特定链表进行一些更改(例如删除特定节点或其他一些操作)时,我们是否使用这种方法?另外,在这里将“n1”和“n2”称为指针是否合适?我知道 java 中不存在指针的概念,但是在面试中尝试解释时,这些变量的合适名称是什么?
  • 当您可能正在更改头节点时是合适的。 Java中确实存在指针,否则不会有NullPointerException:但是它们是Pascal意义上的指针,而不是C意义上的指针。指针要么为空,要么为对象引用。但在面试中,称他们为推荐人可能更安全,因为面试官并不总是像他们应有的那样知识渊博。

标签: java algorithm linked-list


【解决方案1】:

如果要交换链表中的两个节点,则需要更改这些节点中的next 指针和前一个节点。

例如,您有一个列表A->B->C,并且您想交换B 和C,您需要更改这些节点所有 中的next 指针。

如果你想交换 first 两个节点,那么你需要改变这两个节点中的next 指针和指向头的指针列表。

所以,你要做的事情取决于你是否在列表的开头交换......但是你的函数的作者很懒,他不想写两个不同的各种交换代码。

先生。因此,懒惰的程序员在他必须交换的所有东西之前卡在一个虚拟节点中。这样他就不必在开始时交换任何东西,并且他可以对所有交换使用相同的代码。他在最后删除了这个节点,所以没有造成任何伤害。

在 Java 中创建一个虚拟节点并没有那么昂贵,但我不会这样做。

我会这样写出两种方式:

public ListNode swapPairs(ListNode head) {
    
    if (head != null && head.next != null) {

        //swap first 2 nodes
        ListNode n1 = head;
        ListNode n2 = n1.next;

        head = n2;
        n1.next = n2.next;
        n2.next = n1;                   
        ListNode pred = n1;

        //swap remainder
        while (pred.next != null && pred.next.next != null) {
            n1 = pred.next;
            n2 = n1.next;

            pred.next = n2;
            n1.next = n2.next;
            n2.next = n1;                   
            pred = n1;
        }
    }
    return head;
}

【讨论】:

  • 所有程序员都应该偷懒。我会说这是一个很好的解决方案。
  • @EJP 程序员应该仔细挑选他们懒惰的东西。我的代码不会长很多,不需要关于 SO 的问题即可理解,而且无论 ListNode 中可能包含什么其他内容,它都很快。
  • @Matt Timmermans,很好的解决方案,但是if (head != null || head.next != null) 这一行应该与&& 一起使用,否则它可能会返回空指针异常。
【解决方案2】:

根本不需要添加虚拟节点。实际上,您通过添加虚拟节点作为头来更改链表的头。您的代码应该可以在没有虚拟节点的情况下工作。

public void swapPairs(ListNode head) {

    if(head!=null) {
      while (head.next != null && head.next.next != null) {
        ListNode n1 = head.next, n2 = head.next.next;

        head.next = n2;
        n1.next = n2.next;
        n2.next = n1;

        head = n1;
      }
    }
}

【讨论】:

  • 您好,感谢您的回答。您能否告诉我添加节点会有所帮助的情况。感谢并感谢您的帮助。
  • OP 的代码没有添加一个虚拟节点作为头部,并且此代码不返回新的头部。它似乎也失去了大部分列表。
猜你喜欢
  • 2010-11-10
  • 1970-01-01
  • 2016-02-15
  • 1970-01-01
  • 1970-01-01
  • 2014-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多