题目
思路
我的思路是直接利用双指针,找到倒数第N个节点的前驱节点,利用前驱节点删除倒数第N个节点。
我的代码实现(Java)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode front = head,next = head;
while(n!=0 && next.next!=null) { //这里先让next指针走到front 的前 n-1 个节点
next = next.next;
n--;
}
while(next.next!=null) { //然后 前后指针一起往后走
front = front.next;
next = next.next;
}
if(front == head && n == 1) //如果 front 还是没变化并且 n = 1,则说明 front 就是我要删除的节点,直接返回 head.next
return head.next;
if(front.next != null) { //这个就是普通情况,front就是倒数第N个节点的前驱节点
front.next = front.next.next;
} else {
head = null; //如果为空,则头节点置空 样例:[1],1
}
return head;
}
}
官方的代码实现(Java)
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) {
first = first.next;
}
while (first != null) {
first = first.next;
second = second.next;
}
second.next = second.next.next;
ListNode ans = dummy.next;
return ans;
}
}
对比
代码优雅度
从代码优雅度来看,官网的实现巧妙的运用了一个哑节点减少了很多边界情况,因此很少判断语句,更加简洁。我个人实现的代码没有利用到哑节点,直接在原来的链表上操作,不写注释的话,比较难懂,只有个人去调试各种情况,才可以理解代码,比较冗长。
效率对比
我的代码
官网代码
我的代码因为减少了哑节点的内存开销,所以空间消耗更少,但是在时间上消耗上,我的代码要做多次判断条件,所以时间消耗更长,但是从结果上看不出来很大的差异。
总结
刷链表的题目,可以多想想是否可以用得到哑节点提高自己的代码优雅程度,哑节点的加入,使得思路更加清晰易懂。这是一种思想:消耗一定的代价,使得代码更容易懂,更加优雅,更容易扩展维护。有点设计模式那味道了。😄😄
坚持分享,坚持原创,喜欢博主的靓仔靓女们可以看看博主的首页博客!
您的点赞与收藏是我分享博客的最大赞赏!
博主博客地址: https://blog.csdn.net/weixin_43967679