1
+ // 19. 删除链表的倒数第 N 个结点
2
+
3
+
4
+ /**
5
+ * Definition for singly-linked list.
6
+ * public class ListNode {
7
+ * int val;
8
+ * ListNode next;
9
+ * ListNode() {}
10
+ * ListNode(int val) { this.val = val; }
11
+ * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
12
+ * }
13
+ */
14
+
15
+
16
+ /*
17
+ 快慢指针:快指针先走n步,然后快慢指针同时走,直到快指针走完链表,此时慢指针所指节点的下一节点是待删除节点,修改慢指针所指节点的下一节点指针指向为下下节点
18
+ */
19
+ class Solution {
20
+ public ListNode removeNthFromEnd (ListNode head , int n ) {
21
+ ListNode root = new ListNode (0 , head );
22
+ ListNode slow = root ;
23
+ ListNode fast = head ;
24
+ for (int i = 0 ; i < n ; i ++) {
25
+ fast = fast .next ;
26
+ }
27
+ while (fast != null ) {
28
+ fast = fast .next ;
29
+ slow = slow .next ;
30
+ }
31
+ slow .next = slow .next .next ;
32
+ return root .next ;
33
+ }
34
+ }
35
+
36
+
37
+ /*
38
+ 栈:后进先出,全部入栈后弹出n个节点,第n个为待删除节点,此时栈顶节点为前驱节点,修改前驱节点的下一节点指针指向下下节点
39
+ */
40
+ class Solution {
41
+ public ListNode removeNthFromEnd (ListNode head , int n ) {
42
+ Stack <ListNode > stack = new Stack <>();
43
+ ListNode root = new ListNode (0 , head );
44
+ ListNode cur = root ;
45
+ while (cur != null ) {
46
+ stack .push (cur );
47
+ cur = cur .next ;
48
+ }
49
+ while (n > 0 ) {
50
+ stack .pop ();
51
+ n --;
52
+ }
53
+ ListNode node = stack .peek ();
54
+ node .next = node .next .next ;
55
+ return root .next ;
56
+ }
57
+ }
58
+
59
+
60
+ /*
61
+ 计数:遍历链表记录链表长度,计算待删除节点正数位置,再从头遍历到待删除节点的前驱节点位置,修改前驱节点的下一节点指针指向下下节点
62
+ */
63
+ class Solution {
64
+ public ListNode removeNthFromEnd (ListNode head , int n ) {
65
+ ListNode root = new ListNode (0 , head );
66
+ ListNode cur = root ;
67
+ int len = 0 ;
68
+ while (head != null ) {
69
+ len ++;
70
+ head = head .next ;
71
+ }
72
+ for (int i = 0 ; i < len - n ; i ++) {
73
+ cur = cur .next ;
74
+ }
75
+ cur .next = cur .next .next ;
76
+ return root .next ;
77
+ }
78
+ }
79
+
80
+
81
+ /*
82
+ 递归:累加计数
83
+ 1、方法功能:传入节点,返回该节点的倒数位置个数。如果是目标删除位置,则修改链表指针指向下下个节点
84
+ 2、终止条件:节点为空时,返回位置0
85
+ 3、递归逻辑:
86
+ 1)调用递归方法,直接走到链表尾部,逐层累加计数返回
87
+ 2)接收递归返回值,判断该值是否为目标删除位置,是则说明下一节点是待删除节点,修改链表指针指向下下个节点
88
+ */
89
+ class Solution {
90
+ public ListNode removeNthFromEnd (ListNode head , int n ) {
91
+ return rec (head , n ) == n ? head .next : head ;
92
+ }
93
+
94
+ private int rec (ListNode head , int n ) {
95
+ if (head == null ) {
96
+ return 0 ;
97
+ }
98
+ int num = rec (head .next , n );
99
+ if (num == n ) {
100
+ head .next = head .next .next ;
101
+ }
102
+ return ++num ;
103
+ }
104
+ }
105
+
106
+
107
+ /*
108
+ 递归:递减计数
109
+ */
110
+ class Solution {
111
+ public ListNode removeNthFromEnd (ListNode head , int n ) {
112
+ return track (head , n ) == 0 ? head .next : head ;
113
+ }
114
+
115
+ private int track (ListNode head , int num ) {
116
+ if (head == null ) {
117
+ return num ;
118
+ }
119
+ num = track (head .next , num );
120
+ if (num == 0 ) {
121
+ head .next = head .next .next ;
122
+ }
123
+ return --num ;
124
+ }
125
+ }
0 commit comments