[英]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
值包裝在一個類中並傳遞它。
我有兩個問題:
為什么第一個解決方案在Java中不起作用? 為什么在每個方法調用中通過局部變量i
的值傳遞與傳遞引用版本不同?
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.