添加一个哑节点(dummy node),它的 nextnext 指针指向链表的头节点
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0, head);
int length = getLength(head);
ListNode cur = dummy;
for (int i = 0; i < length - n ; ++i) {
cur = cur.next;//指针移动
}
cur.next = cur.next.next;//删除
ListNode ans = dummy.next;
return ans;
}
public int getLength(ListNode head) {
int length = 0;
while (head != null) {
++length;
head = head.next;
}
return length;
}
}
2、栈(先进后出)
在遍历链表的同时将所有节点依次入栈
Stack stack = new Stack<>();
stack.push();//入栈 | stack.peek();//查看拿到栈顶元素 不删除 |
stack.pop();//出栈 删除栈顶元素 | stack.empty();//判断栈是否为空 |
stack.search(2);//返回从栈顶往前数第size(2)- i(i为栈下标)个元素 | stack.size() |
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0, head);
Deque<ListNode> stack = new LinkedList<ListNode>();//栈
ListNode p = dummy;
while (p!=null){
stack.push(p);//进栈
p=p.next;
}
//出栈
for (int i = 0; i < n; i++) {
stack.pop();
}
ListNode prev = stack.peek();
prev.next=prev.next.next;
ListNode ans = dummy.next;//去掉哑节点
return ans;
}
}
3、双指针
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0, head);
ListNode first = head;
ListNode second = dummy;
for (int i = 0; i < n; ++i) {
//second指针找到待删除节点
first = first.next;
}
while (first != null) {
first = first.next;
second = second.next;
}
second.next = second.next.next;
ListNode ans = dummy.next;
return ans;
}
}