【问题标题】:Find Merge Point of Two Lists by reversing the Lists通过反转列表找到两个列表的合并点
【发布时间】:2015-09-30 00:35:22
【问题描述】:

问题陈述: 您将获得指向两个链表的头节点的指针,这些链表在某个节点处合并在一起。找到发生这种合并的节点。两个头节点将不同,并且都不会为 NULL。

输入格式 您必须完成 int FindMergeNode(Node* headA, Node* headB) 方法,该方法接受两个参数 - 链表的头。您不应该从标准输入/控制台读取任何输入。

输出格式 找到两个列表合并的节点并返回该节点的数据。不要将任何内容打印到标准输出/控制台。

我试图颠倒这两个列表,然后分别遍历它们中的每一个,直到到达最后一个公共节点。但是在测试时,它没有给出正确的输出。 是我的想法错了还是我的代码错了?这是好方法还是坏方法?

我的代码:

 int FindMergeNode(Node headA, Node headB) {

//Reverse listA
Node currentA = headA;
Node prevA = null;
Node NextA;
while(currentA!=null){
   NextA = currentA.next;
   currentA.next = prevA;
   prevA = currentA;
   currentA = NextA;
}
headA = prevA;

//Reverse listB
Node currentB = headB;
Node prevB = null;
Node NextB;
while(currentB!=null){
   NextB = currentB.next;
   currentB.next = prevB;
   prevB = currentB;
   currentB = NextB;
}
headB = prevB;

//Iterate throught the reversed list and find the last common node.
Node n = headA;
Node m = headB;
while(n.next!=m.next){
    n = n.next;
    m = m.next;
}

return n.data;
}

问题链接:https://www.hackerrank.com/challenges/find-the-merge-point-of-two-joined-linked-lists

编辑:根据 karthik 的回答,我修改了第三个 while 循环,但它仍然给出了错误的输出。

 //Iterate throught the reversed list and find the last common node.
 Node n = headA;
 Node m = headB;
 while(n.next == m.next){
    n = n.next;
    m = m.next;
}

return n.data;

【问题讨论】:

  • Node* 不是 java 语法,可能是 C 或 C++ 程序?如果是这样,请更改标签

标签: java data-structures merge linked-list nodes


【解决方案1】:

编辑:您的解释应该更清楚。因为merge 如果您的意思是合并值,则反转方法有效。但是,如果您的意思是合并实际节点,显然反转方法不起作用,因为当您反转列表时,merging point 只能有下一个指针。

  A->B->C  
          \
            I->J->K
          /
     X->Y

如果这是您的列表,那么当您反转时,您当然不能同时将 CY 作为您的下一个指针。因为当您反转时,您的树会变成

              A<-B<-C
                       I<-J<- K
                X <-Y

但是您的I 将指向YC,具体取决于稍后反转。

另一种更简单的方法(明智的实现) 是将节点推入两个 stacks,一旦完成所有节点,就开始 poping 元素并返回最后一个节点是一样的。

 Stack<Node> stackA - push all elements of listA into stackA;
 Stack<Node> stackB - push all elements of listB into stackA;

 Node result=null;
 while(stackA.peek() == stackB.peek()){
    result = stackA.pop();
    stackB.pop();
 }
 return result;

以下解释回答了您最初的问题

我没有检查您的 reversing the list 逻辑,但之后的 while 循环(第三个 while 循环)肯定是错误的:

  while(n.next!=m.next){  
     n = n.next;
     m = m.next;
 }

重点是——应该是n.next == m.next

  // ideally you should also check (n!=null && m!=null) 
  // it handles the case where there is no common point
  while(n!=null && m!=null && n.next == m.next){
     n = n.next;
     m = m.next;
 }
 return (n == null || m == null)? null : n;

因为你想找到第一个不同的节点并返回上一个节点。

【讨论】:

  • 谢谢,但不用了。我更正了第三个 while 循环,但它仍然给出错误的输出。我已经给出了问题的链接。我喜欢你更简单的方法,比我的要好得多。谢谢。
  • @Charan 是的,它不起作用,因为你的方法不正确,你应该更清楚地解释这个问题。我编辑了答案,检查一下。
【解决方案2】:

我也有来自here 的这个问题和我最快的解决方案:

int FindMergeNode(Node headA, Node headB) {
    int s1 = getSize(headA), s2 = getSize(headB);
    for(int i = 0; i<Math.abs(s1-s2); i++){
        if(s1>s2) headA = headA.next;
        else headB = headB.next;
    }
    while(headA!=null){
        if(headA==headB) return headA.data;
        headA = headA.next;
        headB = headB.next;
    }
    return 0;

}
int getSize(Node head){
    int i = 0;
    while(head!=null){ 
        head = head.next;
        i++;
    }
    return i;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-26
    • 1970-01-01
    • 1970-01-01
    • 2018-10-14
    • 1970-01-01
    相关资源
    最近更新 更多