19. Remove Nth Node From End of List
题目描述和难度
- 题目描述:
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
- 题目难度:中等。
- 英文网址:19. Remove Nth Node From End of List 。
- 中文网址:19. 删除链表的倒数第N个节点 。
思路分析
求解关键:其实只要掌握了如何找到距离末尾 n 个元素的位置,就很容易了。还要注意的就是边界值的选取,其实往往我们认为的值与正确值无非就是 +1 或者 -1 ,为了避免因为粗心出错,我们可以拿一个具体的例子。
另外,涉及链表头结点的操作,一般都会引入虚拟节点,以减少讨论的可能,这是一个常见的技巧。
参考解答
参考解答1
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
public ListNode(int[] nums) {
if (nums == null || nums.length == 0) {
throw new IllegalArgumentException("arr can not be empty");
}
this.val = nums[0];
ListNode curr = this;
for (int i = 1; i < nums.length; i++) {
curr.next = new ListNode(nums[i]);
curr = curr.next;
}
}
@Override
public String toString() {
StringBuilder s = new StringBuilder();
ListNode cur = this;
while (cur != null) {
s.append(cur.val + " -> ");
cur = cur.next;
}
s.append("NULL");
return s.toString();
}
}
public class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyNode = new ListNode(-1);
dummyNode.next = head;
ListNode curNode = dummyNode;
// 要走 n 步
while (curNode != null && n != -1) {
curNode = curNode.next;
n--;
}
ListNode pre = dummyNode;
while (curNode != null) {
pre = pre.next;
curNode = curNode.next;
}
// 走到这里 curNode == null ,即 来到了链表的尾结点
// 并且 pre 来到了要删除结点的下一个结点
ListNode deleteNode = pre.next;
pre.next = deleteNode.next;
deleteNode.next = null;
return dummyNode.next;
}
public static void main(String[] args) {
int[] nums = new int[]{1, 2};
int n = 2;
ListNode head = new ListNode(nums);
Solution solution = new Solution();
ListNode removeNthFromEnd = solution.removeNthFromEnd(head, n);
System.out.println(removeNthFromEnd);
}
}
本篇文章的地址为 https://liweiwei1419.github.io/leetcode-solution/leetcode-0019-remove-nth-node-from-end-of-list ,如果我的题解有错误,或者您有更好的解法,欢迎您告诉我 liweiwei1419@gmail.com 。