18
18
Given n will always be valid.
19
19
Try to do this in one pass.*/
20
20
public class RemoveNthNodeFromEndOfList {
21
- public ListNode removeNthFromEnd (ListNode head , int n ) {
21
+
22
+ /**Naive/most straightforward approach:
23
+ * go through the list, find its total length, then go through the list a second time:
24
+ * this time, pause at the delta point, then assign its next.next pointer to next.
25
+ * This approach has to traverse the list twice, not one-pass.*/
26
+ public ListNode removeNthFromEnd_two_passes (ListNode head , int n ) {
22
27
ListNode temp = head ;
23
28
int len = 0 ;
24
29
while (temp != null ){
@@ -40,10 +45,58 @@ public ListNode removeNthFromEnd(ListNode head, int n) {
40
45
}
41
46
42
47
public static void main (String ...strings ){
48
+ int n = 2 ;
43
49
ListNode head = new ListNode (1 );
44
50
head .next = new ListNode (2 );
45
51
RemoveNthNodeFromEndOfList test = new RemoveNthNodeFromEndOfList ();
46
- ListNode res = test .removeNthFromEnd (head , 2 );
52
+ // ListNode res = test.removeNthFromEnd_two_passes(head, n);
53
+ ListNode res = test .removeNthFromEnd_one_pass (head , n );
47
54
CommonUtils .printList (res );
48
55
}
56
+
57
+ public ListNode removeNthFromEnd_one_pass (ListNode head , int n ) {
58
+ //this approach uses two pointers, fast moves first for n nodes, when fast reaches n, then we start to move slow
59
+ //then, when fast reaches null, slow reaches the point where the node should be deleted.
60
+ ListNode dummy = new ListNode (-1 );
61
+ dummy .next = head ;
62
+ ListNode slow = head , fast = head ;
63
+ int tempN = n ;
64
+ while (tempN -- > 0 ){
65
+ fast = fast .next ;
66
+ }
67
+
68
+ if (fast == null ) {
69
+ if (n > 0 ) {
70
+ // this is for cases like this: [1,2] 2 or [1,2,3,4] 4, namely, remove the head of
71
+ // the list and return the second node from the original list
72
+ dummy .next = dummy .next .next ;
73
+ }
74
+ return dummy .next ;
75
+ }
76
+
77
+ fast = fast .next ;//we'll have to move fast pointer one node forward before moving the two together, this way,
78
+ //when fast reaches null, slow will be at the previous node to the node that should be deleted, thus, we can change the next pointer easily
79
+
80
+ while (fast != null ){
81
+ fast = fast .next ;
82
+ slow = slow .next ;
83
+ }
84
+
85
+ if (slow .next != null ) slow .next = slow .next .next ;
86
+ return dummy .next ;
87
+ }
88
+
89
+ //a more concise version using the same idea found on Discuss
90
+ public ListNode removeNthFromEnd_one_pass_more_concise_version (ListNode head , int n ) {
91
+ ListNode dummy = new ListNode (-1 );
92
+ dummy .next = head ;
93
+ ListNode slow = dummy , fast = dummy ;
94
+ while (fast .next != null ){
95
+ if (n <= 0 ) slow = slow .next ;
96
+ fast = fast .next ;
97
+ n --;
98
+ }
99
+ if (slow .next != null ) slow .next = slow .next .next ;
100
+ return dummy .next ;
101
+ }
49
102
}
0 commit comments