您的位置:首页 > 其它

每日一恋 - LeetCode 203 & 19 & 237. Remove Linked List Elements(删除链表中的节点)

2018-08-10 15:00 260 查看

203. 删除链表中的节点

Remove all elements from a linked list of integers that have value val.

Example:

Input:  1->2->6->3->4->5->6, val = 6
Output: 1->2->3->4->5

删除链表中等于给定值 val 的所有节点。

示例:

输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5

解法一(Iteration):

首先处理链头就遇到待删除元素的情况,直到链头不是待删除元素,接着判断是否为空。若不为空,则判断下一个结点是否为空,不为空就检查其是否是待删除元素,若是则将当前结点的 next 指针指向当前结点 next 的 next 的结点,否则就继续遍历链表。

public ListNode removeElements(ListNode head, int val) {

while (head != null && head.val == val) {
head = head.next;
}

if (head == null)
return null;

ListNode prev = head;
while (prev.next != null) {
if (prev.next.val == val) {
prev.next = prev.next.next;
} else {
prev = prev.next;
}
}
return head;
}

解法二(Virtual Head Node):

解法一的优化,增加一个虚拟的头结点,不需要再对输入的头结点进行判断空和是否是删除元素的特殊处理。

public ListNode removeElements(ListNode head, int val) {
ListNode dummyNode = new ListNode(-1);
dummyNode.next = head;
ListNode prev = dummyNode;
while (prev.next != null) {
if (prev.next.val == val) {
prev.next = prev.next.next;
} else {
prev = prev.next;
}
}
return dummyNode.next;
}

解法三(Recursion):

解法一的递归写法,注意在不删除当前结点的情况下,需要将当前结点指向递归完成后的头结点。

public ListNode removeElements(ListNode head, int val) {

if (head == null)
return null;

ListNode res = removeElements(head.next, val);
if (head.val == val)  // 将删除当前结点
return res;
else { // 不删除当前结点
head.next = res;
return head;
}
}

或者

public ListNode removeElements(ListNode head, int val) {
if (head == null) return null;
head.next = removeElements(head.next, val);
return head.val == val ? head.next : head;
}

如果文章里有说得不对的地方请前辈多多指正~ 与君共勉~

19. 删除链表的倒数第N个节点

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

说明:

给定的 n 保证是有效的。

进阶:

你能尝试使用一趟扫描实现吗?

分析

题目要求一趟遍历删除倒数的第n个节点,我们不知道链表的长度,该如何知道第n个节点是哪个呢。其实可以使用快、慢两个指针来完成这一目标,快指针从链头开始先走n个节点,然后慢指针从链头出发,两者同时向前移动,当快指针到达末尾时,慢指针所在位置就是倒数第n个节点的前一个节点,这时候只要跳过它指向它的下一个节点即可。

public ListNode removeNthFromEnd(ListNode head, int n) {

ListNode fast = head;
// 快指针先走 n 步
for (int i = 0 ; i < n ; i ++) {
fast = fast.next;
}

ListNode slow = head;
// 要删除第一个的情况
if (fast == null) {
return head.next;
}

// 当快指针走到结尾时,慢指针就是待删除结点的前一个结点
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}

slow.next = slow.next.next;

return head;
}

237. 删除链表中的节点

这道题与上一题乍一看都是删除链表中的一个节点,但不同的是这题给的不是整个链表,而是待删除的节点。我们知道要删除一个节点需要它的前驱节点的指针,但是这里是无法得到的,只能想一个变通的方法。所以仔细一想,只要交换给定节点和其下一个节点的内容,然后删除下一个节点,这样不就可以了。

public void deleteNode(ListNode node) {
node.val = node.next.val;
ListNode nextNode = node.next;
node.next = nextNode.next;
nextNode.next = null; // 别忘了置为null,垃圾回收
}
阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐