如何在一次迭代中走到奇异链表的中间?

时间:2010-12-22 12:36:46

标签: java data-structures

最近我被问到一个问题,在一个单独的链表中,我们如何在一次迭代中进入列表的中间位置。

A --> B --> C --> D (even nodes)

为此它应该返回指向B的地址

A --> B --> C (odd nodes)

对此也应该返回指向B的地址

有一个解决方案是采取两个指针,一个移动一次,其他移动两次,但它似乎没有在这里工作

LinkedList p1,p2;

while(p2.next != null)
{
    p1 = p1.next;
    p2 = p2.next.next;

}

System.out.print("middle of the node" + p1.data); //This does not give accurate result in odd and even

如果有人以前这样做过,请帮忙。

7 个答案:

答案 0 :(得分:6)

基本算法是

0 拿两个指针

1 同时指向第一个节点

2 首先使用两个节点递增,如果成功,则首先递增,然后再次遍历一个节点

3 当第二个到达结束时,第一个将在中间。

更新:

它肯定会在奇数的情况下工作,即使你需要再检查一个条件,如果第一个点允许移动 next 而不是旁边接下来然后两个指针都在中间,您需要决定将哪个作为中间

alt text

答案 1 :(得分:5)

除非成功高级p2两次,否则无法前进p1;否则,如果列表长度为2,则最终都会指向末尾(并且您指示甚至长度列表应该朝向开头舍入)。

所以:

while ( p2.next != null ) {
    p2 = p2.next;
    if (p2.next != null) {
        p2 = p2.next;
        p1 = p1.next;
    }
}

答案 2 :(得分:1)

我知道你已经接受了答案,但这整个问题听起来像是一种聪明的练习,而不是试图获得正确的解决方案。当你能在O(n / 2)中做到时,为什么要用O(n)做某事?

编辑:这用于断言O(1)性能,这根本就不正确。感谢ysth指出这一点。

在实践中,您将在零迭代中执行此操作:

LinkedList list = ...
int size = list.size();
int middle = (size / 2) + (size % 2 == 0 ? 0 : 1) - 1; //index of middle item
Object o = list.get(middle);  //or ListIterator it = list.listIterator(middle);

答案 3 :(得分:0)

采取两个指针和一个移动一半的速率的解决方案应该工作正常。最有可能的不是解决方案,而是您的实际实施问题。发布有关实施的更多详细信息。

答案 4 :(得分:0)

static ListElement findMiddle(ListElement head){
    ListElement slower = head;
    ListElement faster = head;
    while(faster.next != null && faster.next.next !=null ){
        faster = faster.next.next;
        slower = slower.next;
    } 
    return slower;
}

答案 5 :(得分:0)

public static Node middle(Node head){

    Node slow=head,fast=head;
    while(fast!=null& fast.next!=null && fast.next.next!=null){

         slow=slow.next;
         fast=fast.next.next;                   
    } 


    if(fast!=null && fast.next!=null){
        slow=slow.next;
    }


    return slow;

} 

答案 6 :(得分:0)

public ListNode middleNode(ListNode head) {
    if(head == null) return head;

    ListNode slow = head;
    ListNode fast = head;
    while(fast != null && fast.next != null) {
        fast = fast.next.next;
        slow = slow.next;
    }

    return slow;
}