【问题标题】:shift every other elements of linkedlist (in place) to end of linkedlist in java将链表的所有其他元素(就地)移动到java中链表的末尾
【发布时间】:2014-02-23 06:31:31
【问题描述】:

问题如下: 给定linked list,将备用indices 移到list 的后面

例如:

input:         :  [0] -> [1] -> [2] -> [3] -> [4] -> [5] -> [6] -> [7]
expected output:  [0] -> [2] -> [4] -> [6] -> [1] -> [3] -> [5] -> [7] /

从预期的输出中可以看出,奇数位置(索引)的元素被移动到linkedlist 的后面。我试图实现这一点;我可以删除奇数索引,但它们没有链接到列表的末尾。

我的代码在这里:

public void shift(){
    if (front==null) return;

    ListNode curr=front;
    ListNode temp=curr.next;
    while (curr.next!=null && curr.next.next!=null){
        curr.next=curr.next.next;
        curr=curr.next;
        temp.next=curr.next;
     }
     curr.next=temp;
    temp.next=null;
}


expected output: front -> [0] -> [2] -> [4] -> [6] -> [1] -> [3] -> [5] -> [7] /
my output: front -> [0] -> [2] -> [4] -> [6] -> [1] /

我需要一些帮助

P.S:不得使用辅助存储。没有其他容器!!!所以这是一个就地重新安排

【问题讨论】:

    标签: java algorithm linked-list singly-linked-list


    【解决方案1】:

    形成一个包含奇数索引元素的列表和另一个包含偶数索引元素的列表。将奇数列表附加到偶数列表。时间复杂度为O(n),辅助空间复杂度为O(1)。

        public void shift() {
           if (front == null)
                return;
            ListNode oddList, even, odd;
            oddList = even = odd = front;
            oddList = front.next;
            while (even.next != null) {
                odd.next = even.next;
                odd = even.next;
                even.next = odd.next;
                if(odd.next != null) {
                    even = odd.next;
                    odd.next = null;
                } else {
                    odd.next = null;
                    break;
                }
            }
            if(oddList != null) {
                even.next = oddList;
            }
            //"front" points to the start of the new list.
       }
    

    【讨论】:

    • @VinodKumar:这个有效!。在您的 while 循环中,第一行 odd.next = even.next; 在开头指向同一个节点,即 even.next 和odd.next 相同..?
    • 是的。奇数索引元素使用odd.next = even.next 链接;就像,前一个奇数的下一个是当前偶数的下一个(这是当前奇数)
    【解决方案2】:

    您需要存储对列表后面的引用。然后,遍历列表,并将所有其他元素添加到末尾。

    public void shift() {
        if (front == null)
            return;
    
        ListNode curr = front;
        ListNode temp;
        ListNode back = front;
        while (back.next != null)
            back = back.next;
        ListNode originalBack = back;
    
        while (curr.next != originalBack){
            temp = curr.next;
            curr.next = curr.next.next;
            temp.next = null;
            back = back.next = temp;
            curr = curr.next;
        }
    }
    

    【讨论】:

    • 我猜这将是 O(n^2)。我想应该可以单次遍历列表。
    • 不,不是。你真的,真的,真的需要对列表后面的引用,这样你就可以把元素放在那里。
    • 它是 O(n) 但你正在进行两次遍历。我最初的想法是将删除的链接附加到指向 index-1 的指针上。最后,当前将在列表的末尾。所以我将 current.next 链接到 index-1 处的指针(附加了其他链接)..这有意义吗?
    【解决方案3】:

    在遍历时,弹出所有其他项目,并将它们链接在一起以形成第二个列表。当您到达第一个列表的末尾时,附加第二个列表。我在我的 ipad 上,所以我不能编码,但我一上网就会发帖。

    【讨论】:

    • 我忘了说;不应使用辅助列表。我会更新我的问题
    【解决方案4】:

    朋友可以这样做,希望对你有帮助

    public void shift(){
        if (front==null) return;
    
        ListNode curr=front;
        ListNode temp=curr.next;
        while (curr.next!=null){
            curr.next=curr.next.next;
            curr=curr.next;
    
         }
         curr.next=temp;
    
    }
    
    
    
    
    after 1st pass 0->2, 
    after 2nd pass 1->3,
    after 3rd pass 2->4, 
    after 4th pass 3->5,
    after 5th pass 4->6, 
    after 6th pass 5->7,
    
    and then 7->next is null so we assign tmp to it which is pointing to 1.
    

    【讨论】:

    • @user1988876,我的朋友,我已经编辑了我的代码以获得更好的解释。
    • 尝试运行它看看,我试过了,它给出了[0] -> [2] -> [4] -> [6] -> [1] ,这与我上面得到的类似
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-12
    • 2013-12-21
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    相关资源
    最近更新 更多