Đảo ngược danh sách liên kết trong Java, một cách đệ quy


101

Tôi đã làm việc trên một dự án Java cho một lớp học trong một thời gian. Nó là một triển khai của một danh sách liên kết (ở đây được gọi là AddressList, chứa các nút đơn giản được gọi ListNode). Điểm bắt buộc là mọi thứ sẽ phải được thực hiện với các thuật toán đệ quy. Tôi đã có thể làm mọi thứ tốt đẹp không có một phương pháp:public AddressList reverse()

ListNode:

public class ListNode{
  public String data;
  public ListNode next;
}

Ngay bây giờ reversehàm của tôi chỉ gọi một hàm trợ giúp nhận một đối số để cho phép đệ quy.

public AddressList reverse(){
  return new AddressList(this.reverse(this.head));
}

Với chức năng trợ giúp của tôi có chữ ký của private ListNode reverse(ListNode current).

Hiện tại, tôi thấy nó hoạt động lặp đi lặp lại bằng cách sử dụng một ngăn xếp, nhưng đây không phải là những gì đặc tả yêu cầu. Tôi đã tìm thấy một thuật toán trong C đảo ngược đệ quy và chuyển đổi nó sang mã Java bằng tay, và nó hoạt động, nhưng tôi không hiểu gì về nó.

Chỉnh sửa: Đừng bận tâm, tôi đã tìm ra nó trong khi chờ đợi.

private AddressList reverse(ListNode current, AddressList reversedList){
  if(current == null) 
      return reversedList;
  reversedList.addToFront(current.getData());
  return this.reverse(current.getNext(), reversedList);
}

Trong khi tôi ở đây, có ai thấy có vấn đề gì với tuyến đường này không?


2
Không, không có vấn đề gì với giải pháp của bạn. Ngược lại, nó thậm chí còn "tốt hơn" so với giải pháp "Little Lisper" được ưa chuộng ở chỗ nó để nguyên danh sách ban đầu. Điều này sẽ đặc biệt có giá trị trong cài đặt đa lõi, nơi các giá trị bất biến được ưu tiên mạnh mẽ.
Ingo

Câu trả lời:


318

Có một đoạn mã trong một câu trả lời giải thích nó, nhưng bạn có thể thấy dễ dàng hơn khi bắt đầu từ dưới lên, bằng cách hỏi và trả lời những câu hỏi nhỏ (đây là cách tiếp cận trong The Little Lisper):

  1. Ngược lại của null (danh sách trống) là gì? vô giá trị.
  2. Mặt trái của danh sách một phần tử là gì? phần tử.
  3. Đảo ngược của danh sách n phần tử là gì? phần ngược lại của phần còn lại của danh sách theo sau là phần tử đầu tiên.

public ListNode Reverse(ListNode list)
{
    if (list == null) return null; // first question

    if (list.next == null) return list; // second question

    // third question - in Lisp this is easy, but we don't have cons
    // so we grab the second element (which will be the last after we reverse it)

    ListNode secondElem = list.next;

    // bug fix - need to unlink list from the rest or you will get a cycle
    list.next = null;

    // then we reverse everything from the second element on
    ListNode reverseRest = Reverse(secondElem);

    // then we join the two lists
    secondElem.next = list;

    return reverseRest;
}

30
Chà, tôi thích toàn bộ "Ba câu hỏi" đó.
sdellysse 10/12/08

4
Cảm ơn. Câu hỏi nhỏ được cho là cơ sở của việc học Lisp. Nó cũng là một cách để ẩn cảm ứng từ newbs, về cơ bản là mô hình này. Tôi khuyên bạn nên đọc Little Lisper nếu bạn thực sự muốn giải quyết vấn đề này.
plinth

44
ngoại lệ cho những trường hợp ngoại lệ. Tại sao lại sử dụng một lệnh bắt cho một điều kiện đã biết có thể kiểm tra được bằng một if?
Luke Schafer

4
Tôi tin rằng bạn không cần tạo biến: secondElem vì list.next vẫn là secondElem. Sau "ListNode reverseRest = Reverse (secondElem);", trước tiên bạn có thể thực hiện "list.next.next = list" và sau đó là "list.next = null". Và đó là nó.
ChuanRocks

3
Bạn có thể giải thích tại sao list.next = null không? Tôi đã cố gắng để hiểu chu kỳ nhưng không nhận được.
Rohit

29

Tôi đã được hỏi câu hỏi này trong một cuộc phỏng vấn và rất khó chịu vì tôi đã tìm hiểu nó vì tôi hơi lo lắng.

Điều này sẽ đảo ngược một danh sách được liên kết đơn lẻ, được gọi với đảo ngược (head, NULL); vì vậy nếu đây là danh sách của bạn:

1-> 2-> 3-> 4-> 5-> null
nó sẽ trở thành:
5-> 4-> 3-> 2-> 1-> null

    //Takes as parameters a node in a linked list, and p, the previous node in that list
    //returns the head of the new list
    Node reverse(Node n,Node p){   
        if(n==null) return null;
        if(n.next==null){ //if this is the end of the list, then this is the new head
            n.next=p;
            return n;
        }
        Node r=reverse(n.next,n);  //call reverse for the next node, 
                                      //using yourself as the previous node
        n.next=p;                     //Set your next node to be the previous node 
        return r;                     //Return the head of the new list
    }
    

chỉnh sửa: tôi đã thực hiện 6 lần chỉnh sửa này, cho thấy rằng nó vẫn còn một chút khó khăn đối với tôi lol


2
Thành thật mà nói, tôi sẽ hơi bối rối bởi yêu cầu "phải là đệ quy" trong một cuộc phỏng vấn, nếu Java được chỉ định. Nếu không, tôi sẽ đi với p = null; while (n.next! = null) {n2 = n.next; n.next = p; p = n; n = n2;} n.next = p; trả về n ;. Ngăn xếp O (N) dành cho những con chim.
Steve Jessop 10/08/08

Ồ vâng, một kiểm tra vô hiệu trên đầu cũng là Java.
Steve Jessop 10/08/08

23

Tôi đã đi được một nửa chặng đường (cho đến khi null và một nút như được đề xuất bởi plinth), nhưng bị mất dấu sau khi thực hiện cuộc gọi đệ quy. Tuy nhiên, sau khi đọc bài đăng của plinth, đây là những gì tôi nghĩ ra:

Node reverse(Node head) {
  // if head is null or only one node, it's reverse of itself.
  if ( (head==null) || (head.next == null) ) return head;

  // reverse the sub-list leaving the head node.
  Node reverse = reverse(head.next);

  // head.next still points to the last element of reversed sub-list.
  // so move the head to end.
  head.next.next = head;

  // point last node to nil, (get rid of cycles)
  head.next = null;
  return reverse;
}

rất nice.just thích làm khuyết điểm :)
Karthikeyan D

9

Đây là một giải pháp đệ quy khác. Nó có ít mã trong hàm đệ quy hơn một số hàm khác, vì vậy nó có thể nhanh hơn một chút. Đây là C # nhưng tôi tin rằng Java sẽ rất giống.

class Node<T>
{
    Node<T> next;
    public T data;
}

class LinkedList<T>
{
    Node<T> head = null;

    public void Reverse()
    {
        if (head != null)
            head = RecursiveReverse(null, head);
    }

    private Node<T> RecursiveReverse(Node<T> prev, Node<T> curr)
    {
        Node<T> next = curr.next;
        curr.next = prev;
        return (next == null) ? curr : RecursiveReverse(curr, next);
    }
}

8

Thuật toán sẽ cần hoạt động trên mô hình sau,

  • theo dõi người đứng đầu
  • Lặp lại cho đến cuối danh sách liên kết
  • Liên kết ngược

Kết cấu:

Head    
|    
1-->2-->3-->4-->N-->null

null-->1-->2-->3-->4-->N<--null

null-->1-->2-->3-->4<--N<--null

null-->1-->2-->3<--4<--N<--null

null-->1-->2<--3<--4<--N<--null

null-->1<--2<--3<--4<--N<--null

null<--1<--2<--3<--4<--N
                       |
                       Head

Mã:

public ListNode reverse(ListNode toBeNextNode, ListNode currentNode)
{               
        ListNode currentHead = currentNode; // keep track of the head

        if ((currentNode==null ||currentNode.next==null )&& toBeNextNode ==null)return currentHead; // ignore for size 0 & 1

        if (currentNode.next!=null)currentHead = reverse(currentNode, currentNode.next); // travarse till end recursively

        currentNode.next = toBeNextNode; // reverse link

        return currentHead;
}

Đầu ra:

head-->12345

head-->54321

7

Tôi nghĩ đây là giải pháp sạch hơn, giống như LISP

// Example:
// reverse0(1->2->3, null) => 
//      reverse0(2->3, 1) => 
//          reverse0(3, 2->1) => reverse0(null, 3->2->1)
// once the first argument is null, return the second arg
// which is nothing but the reveresed list.

Link reverse0(Link f, Link n) {
    if (f != null) {
        Link t = new Link(f.data1, f.data2); 
        t.nextLink = n;                      
        f = f.nextLink;             // assuming first had n elements before, 
                                    // now it has (n-1) elements
        reverse0(f, t);
    }
    return n;
}

7

Tôi biết đây là một bài viết cũ, nhưng hầu hết các câu trả lời không phải là đệ quy đuôi, tức là chúng thực hiện một số hoạt động sau khi quay lại từ cuộc gọi đệ quy, và do đó không phải là hiệu quả nhất.

Đây là một phiên bản đệ quy đuôi:

public Node reverse(Node previous, Node current) {
    if(previous == null)
        return null;
    if(previous.equals(head))
        previous.setNext(null);
    if(current == null) {    // end of list
        head = previous;
        return head;
    } else {
                    Node temp = current.getNext();
        current.setNext(previous);
        reverse(current, temp);
    }
    return null;    //should never reach here.
} 

Gọi bằng:

Node newHead = reverse(head, head.getNext());

9
bạn tham chiếu đến một biến được gọi là "head" trong phương thức của mình, nhưng biến đó không được khai báo ở bất kỳ đâu.
marathon

nó có lẽ là một phương pháp để lớp Danh sách chứa các thuộc tính đầu Node
ChrisMcJava

4
void ngược (node1, node2) {
if (node1.next! = null)
      đảo ngược (node1.next, node1);
   node1.next = node2;
}
gọi phương thức này là ngược (start, null);

4
public Node reverseListRecursive(Node curr)
{
    if(curr == null){//Base case
        return head;
    }
    else{
        (reverseListRecursive(curr.next)).next = (curr);
    }
    return curr;
}

3
public void reverse() {
    head = reverseNodes(null, head);
}

private Node reverseNodes(Node prevNode, Node currentNode) {
    if (currentNode == null)
        return prevNode;
    Node nextNode = currentNode.next;
    currentNode.next = prevNode;
    return reverseNodes(currentNode, nextNode);
}

Tôi nghĩ đây là giải pháp tốt nhất ... đơn giản, tối ưu hóa đệ quy đuôi và chỉ có một lần kiểm tra null.
sdanzig

2
public static ListNode recRev(ListNode curr){

    if(curr.next == null){
        return curr;
    }
    ListNode head = recRev(curr.next);
    curr.next.next = curr;
    curr.next = null;

    // propogate the head value
    return head;

}

Đây là giải pháp tốt nhất, nhưng không phải là câu trả lời tốt nhất vì không có lời giải thích nào được đưa ra :). Tôi đã tìm ra một giải pháp tương tự lúc đầu nhưng bị mất tham chiếu đầu. Giải pháp này giải quyết điều đó.
OpenUserX03

2

Đảo ngược bằng thuật toán đệ quy.

public ListNode reverse(ListNode head) {
    if (head == null || head.next == null) return head;    
    ListNode rHead = reverse(head.next);
    rHead.next = head;
    head = null;
    return rHead;
}

Bằng cách lặp lại

public ListNode reverse(ListNode head) {
    if (head == null || head.next == null) return head;    
    ListNode prev = null;
    ListNode cur = head
    ListNode next = head.next;
    while (next != null) {
        cur.next = prev;
        prev = cur;
        cur = next;
        next = next.next;
    }
    return cur;
}

Thật không may, đảo ngược đệ quy của bạn là Sai !!
Sree Aurovindh

@SreeAurovindh - Tại sao?
rayryeng

2

Giải pháp này chứng minh rằng không cần đối số.

/**
 * Reverse the list
 * @return reference to the new list head
 */
public LinkNode reverse() {
    if (next == null) {
        return this; // Return the old tail of the list as the new head
    }
    LinkNode oldTail = next.reverse(); // Recurse to find the old tail
    next.next = this; // The old next node now points back to this node
    next = null; // Make sure old head has no next
    return oldTail; // Return the old tail all the way back to the top
}

Đây là mã hỗ trợ, để chứng minh rằng điều này hoạt động:

public class LinkNode {
    private char name;
    private LinkNode next;

    /**
     * Return a linked list of nodes, whose names are characters from the given string
     * @param str node names
     */
    public LinkNode(String str) {
        if ((str == null) || (str.length() == 0)) {
            throw new IllegalArgumentException("LinkNode constructor arg: " + str);
        }
        name = str.charAt(0);
        if (str.length() > 1) {
            next = new LinkNode(str.substring(1));
        }
    }

    public String toString() {
        return name + ((next == null) ? "" : next.toString());
    }

    public static void main(String[] args) {
        LinkNode head = new LinkNode("abc");
        System.out.println(head);
        System.out.println(head.reverse());
    }
}

2

Đây là một cách tiếp cận lặp lại đơn giản:

public static Node reverse(Node root) {
    if (root == null || root.next == null) {
        return root;
    }

    Node curr, prev, next;
    curr = root; prev = next = null;
    while (curr != null) {
        next = curr.next;
        curr.next = prev;

        prev = curr;
        curr = next;
    }
    return prev;
}

Và đây là một cách tiếp cận đệ quy:

public static Node reverseR(Node node) {
    if (node == null || node.next == null) {
        return node;
    }

    Node next = node.next;
    node.next = null;

    Node remaining = reverseR(next);
    next.next = node;
    return remaining;
}

1

Vì Java luôn truyền theo giá trị, nên để đảo ngược đệ quy một danh sách được liên kết trong Java, hãy đảm bảo trả về "đầu mới" (nút đầu sau khi đảo ngược) ở cuối đệ quy.

static ListNode reverseR(ListNode head) {
    if (head == null || head.next == null) {
        return head;
    }

    ListNode first = head;
    ListNode rest = head.next;

    // reverse the rest of the list recursively
    head = reverseR(rest);

    // fix the first node after recursion
    first.next.next = first;
    first.next = null;

    return head;
}

1

PointZeroTwo đã có câu trả lời thanh lịch và tương tự trong Java ...

public void reverseList(){
    if(head!=null){
        head = reverseListNodes(null , head);
    }
}

private Node reverseListNodes(Node parent , Node child ){
    Node next = child.next;
    child.next = parent;
    return (next==null)?child:reverseListNodes(child, next);
}

Đây là hoàn hảo bởi vì bạn không luôn luôn muốn rằng phương pháp danh sách để có danh sách như các đối số nhưng để đảo ngược bản thân với Childs riêng của mình, cảm ơn bạn
Manu

0
public class Singlelinkedlist {
  public static void main(String[] args) {
    Elem list  = new Elem();
    Reverse(list); //list is populate some  where or some how
  }

  //this  is the part you should be concerned with the function/Method has only 3 lines

  public static void Reverse(Elem e){
    if (e!=null)
      if(e.next !=null )
        Reverse(e.next);
    //System.out.println(e.data);
  }
}

class Elem {
  public Elem next;    // Link to next element in the list.
  public String data;  // Reference to the data.
}

0
public Node reverseRec(Node prev, Node curr) {
    if (curr == null) return null;  

    if (curr.next == null) {
        curr.next = prev;
        return curr;

    } else {
        Node temp = curr.next; 
        curr.next = prev;
        return reverseRec(curr, temp);
    }               
}

gọi bằng cách sử dụng: head = reverseRec (null, head);


0

Những gì những người khác đã làm, trong bài viết khác là một trò chơi nội dung, những gì tôi đã làm là một trò chơi của danh sách liên kết, nó đảo ngược thành viên của LinkedList chứ không đảo ngược Giá trị của thành viên.

Public LinkedList reverse(LinkedList List)
{
       if(List == null)
               return null;
       if(List.next() == null)
              return List;
       LinkedList temp = this.reverse( List.next() );
       return temp.setNext( List );
}

sry, tôi quên rằng bạn cũng cần một phương thức trợ giúp để đặt phần tiếp theo của đuôi, với giá trị null
Nima Ghaedsharafi

0
package com.mypackage;
class list{

    node first;    
    node last;

    list(){
    first=null;
    last=null;
}

/*returns true if first is null*/
public boolean isEmpty(){
    return first==null;
}
/*Method for insertion*/

public void insert(int value){

    if(isEmpty()){
        first=last=new node(value);
        last.next=null;
    }
    else{
        node temp=new node(value);
        last.next=temp;
        last=temp;
        last.next=null;
    }

}
/*simple traversal from beginning*/
public void traverse(){
    node t=first;
    while(!isEmpty() && t!=null){
        t.printval();
        t= t.next;
    }
}
/*static method for creating a reversed linked list*/
public static void reverse(node n,list l1){

    if(n.next!=null)
        reverse(n.next,l1);/*will traverse to the very end*/
    l1.insert(n.value);/*every stack frame will do insertion now*/

}
/*private inner class node*/
private class node{
    int value;
    node next;
    node(int value){
        this.value=value;
    }
    void printval(){
        System.out.print(value+" ");
    }
}

 }

0

Giải pháp là:

package basic;

import custom.ds.nodes.Node;

public class RevLinkedList {

private static Node<Integer> first = null;

public static void main(String[] args) {
    Node<Integer> f = new Node<Integer>();
    Node<Integer> s = new Node<Integer>();
    Node<Integer> t = new Node<Integer>();
    Node<Integer> fo = new Node<Integer>();
    f.setNext(s);
    s.setNext(t);
    t.setNext(fo);
    fo.setNext(null);

    f.setItem(1);
    s.setItem(2);
    t.setItem(3);
    fo.setItem(4);
    Node<Integer> curr = f;
    display(curr);
    revLL(null, f);
    display(first);
}

public static void display(Node<Integer> curr) {
    while (curr.getNext() != null) {
        System.out.println(curr.getItem());
        System.out.println(curr.getNext());
        curr = curr.getNext();
    }
}

public static void revLL(Node<Integer> pn, Node<Integer> cn) {
    while (cn.getNext() != null) {
        revLL(cn, cn.getNext());
        break;
    }
    if (cn.getNext() == null) {
        first = cn;
    }
    cn.setNext(pn);
}

}


0
static void reverseList(){

if(head!=null||head.next!=null){
ListNode tail=head;//head points to tail


ListNode Second=head.next;
ListNode Third=Second.next;
tail.next=null;//tail previous head is poiniting null
Second.next=tail;
ListNode current=Third;
ListNode prev=Second;
if(Third.next!=null){



    while(current!=null){
    ListNode    next=current.next;
        current.next=prev;
        prev=current;
        current=next;
    }
    }
head=prev;//new head
}
}
class ListNode{
    public int data;
    public ListNode next;
    public int getData() {
        return data;
    }

    public ListNode(int data) {
        super();
        this.data = data;
        this.next=null;
    }

    public ListNode(int data, ListNode next) {
        super();
        this.data = data;
        this.next = next;
    }

    public void setData(int data) {
        this.data = data;
    }
    public ListNode getNext() {
        return next;
    }
    public void setNext(ListNode next) {
        this.next = next;
    }





}

0
private Node ReverseList(Node current, Node previous)
    {
        if (current == null) return null;
        Node originalNext = current.next;
        current.next = previous;
        if (originalNext == null) return current;
        return ReverseList(originalNext, current);
    }

bắt đầu với ReverseList (head, null)
vỗ vào

0
//this function reverses the linked list
public Node reverseList(Node p) {
    if(head == null){
        return null;
    }
    //make the last node as head
    if(p.next == null){
        head.next = null;
        head = p;
        return p;
    }
    //traverse to the last node, then reverse the pointers by assigning the 2nd last node to last node and so on..
    return reverseList(p.next).next = p;
}

0
//Recursive solution
class SLL
{
   int data;
   SLL next;
}

SLL reverse(SLL head)
{
  //base case - 0 or 1 elements
  if(head == null || head.next == null) return head;

  SLL temp = reverse(head.next);
  head.next.next = head;
  head.next = null;
  return temp;
}

0

Lấy cảm hứng từ một bài báo thảo luận về các triển khai bất biến của cấu trúc dữ liệu đệ quy, tôi đã đưa ra một giải pháp thay thế với nhau bằng cách sử dụng Swift.

Giải pháp tài liệu câu trả lời hàng đầu bằng cách nêu bật các chủ đề sau:

  1. Ngược lại của nil (danh sách trống) là gì?
    • Không quan trọng ở đây, bởi vì chúng tôi có bảo vệ số không trong Swift.
  2. Mặt trái của danh sách một phần tử là gì?
    • Chính yếu tố
  3. Đảo ngược của danh sách n phần tử là gì?
    • Đảo ngược của phần tử thứ hai tiếp theo là phần tử đầu tiên.

Tôi đã gọi chúng ra nếu có thể áp dụng trong giải pháp bên dưới.

/**
 Node is a class that stores an arbitrary value of generic type T 
 and a pointer to another Node of the same time.  This is a recursive 
 data structure representative of a member of a unidirectional linked
 list.
 */
public class Node<T> {
    public let value: T
    public let next: Node<T>?

    public init(value: T, next: Node<T>?) {
        self.value = value
        self.next = next
    }

    public func reversedList() -> Node<T> {
        if let next = self.next {
            // 3. The reverse of the second element on followed by the first element.
            return next.reversedList() + value
        } else {
            // 2. Reverse of a one element list is itself
            return self
        }
    }
}

/**
 @return Returns a newly created Node consisting of the lhs list appended with rhs value.
 */
public func +<T>(lhs: Node<T>, rhs: T) -> Node<T> {
    let tail: Node<T>?
    if let next = lhs.next {
        // The new tail is created recursively, as long as there is a next node.
        tail = next + rhs
    } else {
        // If there is not a next node, create a new tail node to append
        tail = Node<T>(value: rhs, next: nil)
    }
    // Return a newly created Node consisting of the lhs list appended with rhs value.
    return Node<T>(value: lhs.value, next: tail)
}

0

Đảo ngược danh sách liên kết bằng cách sử dụng đệ quy. Ý tưởng là điều chỉnh các liên kết bằng cách đảo ngược các liên kết.

  public ListNode reverseR(ListNode p) {

       //Base condition, Once you reach the last node,return p                                           
        if (p == null || p.next == null) { 
            return p;
        }
       //Go on making the recursive call till reach the last node,now head points to the last node

        ListNode head  = reverseR(p.next);  //Head points to the last node

       //Here, p points to the last but one node(previous node),  q points to the last   node. Then next next step is to adjust the links
        ListNode q = p.next; 

       //Last node link points to the P (last but one node)
        q.next = p; 
       //Set the last but node (previous node) next to null
        p.next = null; 
        return head; //Head points to the last node
    }

1
Bạn có thể vui lòng giải thích thêm câu trả lời của mình bằng cách thêm một chút mô tả về giải pháp bạn cung cấp không?
abarisone

1
Tôi đã thêm ý kiến. Thanks a lot
gurubelli

0
public void reverseLinkedList(Node node){
    if(node==null){
        return;
    }

    reverseLinkedList(node.next);
    Node temp = node.next;
    node.next=node.prev;
    node.prev=temp;
    return;
}

-1
public void reverse(){
    if(isEmpty()){
    return;
     }
     Node<T> revHead = new Node<T>();
     this.reverse(head.next, revHead);
     this.head = revHead;
}

private Node<T> reverse(Node<T> node, Node<T> revHead){
    if(node.next == null){
       revHead.next = node;
       return node;
     }
     Node<T> reverse = this.reverse(node.next, revHead);
     reverse.next = node;
     node.next = null;
     return node;
}

-1

Đây là tài liệu tham khảo nếu ai đó đang tìm kiếm triển khai Scala:

scala> import scala.collection.mutable.LinkedList
import scala.collection.mutable.LinkedList

scala> def reverseLinkedList[A](ll: LinkedList[A]): LinkedList[A] =
         ll.foldLeft(LinkedList.empty[A])((accumulator, nextElement) => nextElement +: accumulator)
reverseLinkedList: [A](ll: scala.collection.mutable.LinkedList[A])scala.collection.mutable.LinkedList[A]

scala> reverseLinkedList(LinkedList("a", "b", "c"))
res0: scala.collection.mutable.LinkedList[java.lang.String] = LinkedList(c, b, a)

scala> reverseLinkedList(LinkedList("1", "2", "3"))
res1: scala.collection.mutable.LinkedList[java.lang.String] = LinkedList(3, 2, 1)

Tôi sẽ rất vui khi cải thiện câu trả lời của mình nếu người đó không đồng ý cho tôi lời giải thích về hành động của anh ta. Dù sao, nó vẫn làm việc cho tôi trong Scala :)
Venkat Reddy Sudheer Aedama

Để downvoter biết, đây là một giải pháp đệ quy (thực tế là đệ quy đuôi).
Venkat Sudheer Reddy Aedama

Scala không phải là Java, ngay cả khi cả hai đều chạy trên JVM.
Bill Lynch

@sharth Chà, thật vui khi biết điều đó. Bạn có buồn đọc dòng đầu tiên trong câu trả lời của tôi không?
Venkat Sudheer Reddy Aedama

@VenkatSudheerReddyAedama Bạn đã bị phản đối vì câu hỏi ban đầu yêu cầu triển khai trong Java. Mặc dù Scala chạy trong JVM, điều này không giúp trả lời câu hỏi ... mặc dù nó khá thanh lịch. FWIW, tôi đã không phản đối bạn.
rayryeng
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.