繁体   English   中英

如何在不使用内置类和方法的情况下,通过 Java 中链表的 k 个节点将元素向左和向右移动?

[英]How can I shift the elements to left and right by k nodes of Linked List in Java without using built in classes and methods?

如何在不使用内置类和方法的情况下,通过 Java 中链表的 k 个节点将元素向左和向右移动? 输入:A->B->C->D n=2(右移2) 输出:C->D->A->B

 public static void shiftListRight(LinkedList linkedList, int n) 
    {
        if(head==null)
        {
            return null;
        }
        int k=1;
        LinkedList tail=head;
        while(tail.getNext()!=null)
        {
            ++k;
            tail=tail.getNext();
        }
        n%=k;
        if(n==0)
            return head;
        int stepsToNewHead= k-n;
        tail.setNext(head);
        List newTail = tail;
        while(stepsToNewHead-- >0)
        {
            newTail.setNext(newTail);
        }
        
        //Implement your code here   

    }
}

这是一个非常简单的算法,您必须使用 3 次for...each带有swap方法的循环。 我给你一个array例子,你可以很容易地将它转换为List

// offs > 0 - shift to the right
public static void shift(int[] arr, int offs) {
    offs %= arr.length;
    offs = offs < 0 ? arr.length + offs : offs;

    for (int i = 0, j = arr.length - 1; i < j; i++, j--)
        swap(arr, i, j);
    for (int i = 0, j = offs - 1; i < j; i++, j--)
        swap(arr, i, j);
    for (int i = offs, j = arr.length - 1; i < j; i++, j--)
        swap(arr, i, j);
}

private static void swap(int[] arr, int i, int j) {
    int tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

输出:

int[] arr1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
System.out.println(Arrays.toString(arr1));  // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
shift(arr1, 3);
System.out.println(Arrays.toString(arr1));  // [7, 8, 9, 0, 1, 2, 3, 4, 5, 6]

System.out.println();

int[] arr2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
System.out.println(Arrays.toString(arr2));  // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
shift(arr2, -3);
System.out.println(Arrays.toString(arr2));  // [3, 4, 5, 6, 7, 8, 9, 0, 1, 2]

根据您问题中的示例输入和输出,我会说您想旋转链表中的元素而不是移动它们。

这是我对题为Java - “Rotating” Objects in A LinkedList - Is LinkedList.addLast(LinkedList.removeFirst()) Good or Bad Programming的 SO 问题的实现 换句话说,下面的代码显示了该问题中提到的addFirst()addLast()removeFirst()removeLast()

public class LinkdLst {
    private ListNode  head;

    public void addFirst(ListNode node) {
        if (node != null) {
            if (head == null) {
                head = node;
            }
            else {
                node.setNext(head);
                head = node;
            }
        }
    }

    public void addLast(ListNode node) {
        if (node != null) {
            if (head == null) {
                head = node;
            }
            else {
                ListNode previous = head;
                ListNode current = head.getNext();
                while (current != null) {
                    previous = current;
                    current = current.getNext();
                }
                previous.setNext(node);
            }
        }
    }

    public ListNode removeFirst() {
        ListNode removed;
        if (head == null) {
            removed = null;
        }
        else {
            removed = head;
            head = head.getNext();
        }
        return removed;
    }

    public ListNode removeLast() {
        ListNode removed;
        if (head == null) {
            removed = null;
        }
        else {
            ListNode previous = null;
            ListNode current = head;
            while (current.getNext() != null) {
                previous = current;
                current = current.getNext();
            }
            removed = current;
            if (previous != null) {
                previous.setNext(null);
            }
            else {
                head = null;
            }
        }
        return removed;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        ListNode current = head;
        while (current != null) {
            sb.append(current);
            current = current.getNext();
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        LinkdLst list = new LinkdLst();
        list.addLast(new ListNode('A'));
        list.addLast(new ListNode('B'));
        list.addLast(new ListNode('C'));
        list.addLast(new ListNode('D'));
        System.out.println(list);
        for (int i = 0; i < 2; i++) {
            list.addLast(list.removeFirst());
        }
        System.out.println(list);
        for (int i = 0; i < 2; i++) {
            list.addFirst(list.removeLast());
        }
        System.out.println(list);
    }
}

class ListNode {
    private char  data;
    private ListNode  next;

    public ListNode(char datum) {
        data = datum;
    }

    public ListNode getNext() {
        return next;
    }

    public void setNext(ListNode node) {
        next = node;
    }

    public String toString() {
        return String.format("%c-> ", data);
    }
}

首先,我根据您问题中的示例创建列表。 然后我也根据您问题中的示例将它们旋转 2 以获得所需的结果。 然后我以相反的方向将“旋转”列表旋转 2,这将“旋转”列表返回到其原始顺序。 这是运行上述代码时的输出。

请注意,上述代码中的toString()方法仅用于调试目的,而不是已实现的解决方案的一部分。 换句话说,您可以安全地删除它们。

A-> B-> C-> D-> 
C-> D-> A-> B-> 
A-> B-> C-> D->

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM