1.問題の説明:
リンクリストが与えられた場合、リンクリストの最後から2番目のノードを削除し、リンクリストのヘッドノードを返します。
例:
リンクされたリストがある場合:1-> 2-> 3-> 4-> 5、およびn = 2。
最後から2番目のノードが削除されると、リンクされたリストは1-> 2-> 3-> 5になります。
説明:
指定されたn保証は有効です。
上級:
ワンパススキャンを使用してみてください。
ソース:LeetCode
リンク:https ://leetcode-cn.com/problems/remove-nth-node-from-end-of-list
2.思考分析:
①最後からn番目のノードを削除するため問題はわかりやすく、再帰で解決しようと考えましたが、再帰はレイヤーごとに解いていくので、この機能で解決できます。 「1回戻り、1回計算する」とは、現在のノード数を意味するため、グローバル変数を使用して、現在、背面から前面に返されているノードの数を記録する必要があります。ノード数を判断することで、削除する必要があるターゲットノード、現在のノードが削除する必要があるノードであることが判明した場合、この層に戻る次のノードが現在のノードであり、このノードを削除する必要があるため、再帰呼び出しの終了の結果を直接返します。次のノードに直接戻るだけで、ノードが接続されている場合、この要素は無視されます
②現在のノードが削除されたノードではないことが判明した場合、現在のノードの次のポインタフィールドを再帰呼び出しによって返された次のノードにポイントする必要があります。つまり、現在のノードを現在のノードの後のノードに接続します(各再帰メソッドの後)次に、返される結果は現在のノードの次のノードです)アイデアは比較的単純です。コードを見るとわかりやすくなっています
③レイヤーごとのリターンの再帰機能、特に結果を後ろから前に計算する必要がある種類の再帰機能を使用することは非常に有益ですが、従来の方法ではこの機能を右から右にしか使用できません。これは非常に便利であり、再帰だけではありません計算は再帰メソッドの前に呼び出すことができ、再帰メソッドの後の呼び出しは後ろから前に行われるため、後ろまたは前からのみ計算できます。
3.コードは次のとおりです。
public class Solution {
int count = 0;
public ListNode removeNthFromEnd(ListNode head, int n) {
/*使用递归来进行修改*/
if (head == null) return null;
ListNode cur = removeNthFromEnd(head.next, n);
count++;
if (count == n){
return cur;
}else{
head.next = cur;
return head;
}
}
}