簡體   English   中英

查找單鏈列表的第k個元素

[英]Finding the kth to last element of a singly linked list

對於Java中的“單鏈列表的第k個元素”,我有兩種遞歸解決方案:

解決方案1:

public static Node nthToLast(Node head, int k , int i){
    if (head == null) return null;
    Node n = nthToLast(head.next, k, i);
    i = i + 1;

    if (i == k) return head;

    return n;
}

解決方案2:

public class IntWrapper {
    public int value = 0;
}
public static Node nthToLast(Node head, int k, IntWrapper i){
    if (head == null) return null;
    Node n = nthToLast(head.next, k, i);
    i.value = i.value + 1;

    if (i.value == k) return head;

    return n;
}

第一個解決方案返回null ,而第二個解決方案完美運行。 第一個解決方案按值傳遞k ,而第二個解決方案將int值包裝在一個類中並傳遞它。

我有兩個問題:

  1. 為什么第一個解決方案在Java中不起作用? 為什么在每個方法調用中通過局部變量i的值傳遞與傳遞引用版本不同?

  2. Java中的Integer類包裝了int ,但是在第一個解決方案中將int替換為Integer並不能正常工作。 為什么?

1.第一種解決方案不起作用,因為每次您在i變量中傳遞相同的值。 如果將行i = i + ​​1移到行Node n = nthToLast (head.next, k, i) ,則一切都應該正常工作。
2. Integer類是不可變的,因此其行為類似於普通的int 這就是為什么如果在第一個解決方案中使用Integer函數將無法正常工作的原因。 您可以替換上面我提到的第一個解決方案與Integer一起使用的代碼行。
第二種解決方案之所以有效,是因為您增加計數器的方式不會覆蓋對計數對象的引用。

在解決方案2中,您正在使用IntWrapper記住跨遞歸調用的值。 在這里, IntWrapper作用就像一個全局值。

如果使用局部變量(例如原始整數),則無法在調用之間保留遞增的( i = i + 1 )值。 因此,語句if (i == k) return head; 除非k = 1。

最有趣的是,您不能使用Integer因為Java包裝器類本質上是不可變的。 當您執行i = i + 1的那一刻,將創建一個新對象(LHS),而一個舊對象(RHS)將被丟棄/收集垃圾。

在您的解決方案1中,您應在遞歸調用該方法之前使i遞增。 這個版本應該工作:

public static Node nthToLast(Node head, int k , int i) {
    // checks empty case
    if (head == null) { return null; }

     // checks if current node is the solution
    if (i == k) { return head; }

    // else checks next node
    return nthToLast(head.next, k, i+1); 
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM