LeetCode 19之Remove Nth Node From End of List的Java题解(三种解法)

来源:互联网 发布:九阴绝学各项数据 编辑:程序博客网 时间:2024/05/06 09:38

题目

Given a linked list, remove the nth node from the end of list and return its head.

For example,

   Given linked list: 1->2->3->4->5, and n = 2.   After removing the second node from the end, the linked list becomes 1->2->3->5.
解题:

第一种解法:

这种解法是最容易想到的,先遍历一遍链表得到链表的长度,知道长度后就可以定位到要删除的节点

代码:

if(head==null||head.next==null)return null;int length=0;ListNode fakeNode=new ListNode(-1);fakeNode.next=head;ListNode pre=fakeNode;ListNode cur=head;//先统计链表长度while(cur!=null){length++;cur=cur.next;}cur=head;//重新置为指向头节点while(cur!=null){if(length==n){pre.next=cur.next;//删除节点break;}pre=pre.next;cur=cur.next;length--;}return fakeNode.next;
第二种解法:

第一种解法需要遍历两遍,效率会显得低一些,常用的思路用空间换时间,我们遍历一遍链表把所有链表都存在一个哈希表中并统计哈希表的长度,知道长度之后也可以很容易定位到需要删除的节点,这时候需要处理要删除的节点为第一个和最后一个的特殊情况。

代码:

if(head==null||head.next==null)return null;ListNode cur=head;Hashtable<Integer, ListNode> ht=new Hashtable<>();int length=0;//把所有节点存在链表中while(cur!=null){length++;ht.put(length, cur);cur=cur.next;}if(length==n)//链表中第一个节点{head=head.next;}else if(n==1)//链表中最后一个节点{ListNode temp=ht.get(length-1);temp.next=null;}else {ListNode temp=ht.get(length-n);temp.next=temp.next.next;}return head;
第三种解法:

有没有不使用额外空间又能够只遍历一遍的解法呢?第三种就是这种解法,它利用两个指针。我先说明一些原理:

利用对称性,数组第一个点到倒数第n个点的距离等于数组最后一个点到顺数第n个点的距离,为了删除倒数第n个点我们要找到它前一个点(即倒数第n+1个点) 利用对称性  我们定义两个指针  先让指针1跑到顺数第n+1个点,到了之后,让指针1和指针2同时跑,当指针1跑到最后一个点的时候,根据对称性,指针2也跑到了倒数第n+1个点这个是最重要的思路,除此之外记得处理两个特殊情况,当要删除的节点位于链表第一个和链表最后一个。当n=1时,链表最后一个点,当N等于链表长度时,链表第一个点。

public static ListNode removeNthFromEnd2(ListNode head, int n) {if(head==null||head.next==null)return null;ListNode cur1=head;ListNode cur2=head;//让指针1跑到顺数第n+1个点while(n!=0){cur1=cur1.next;n--;if(cur1.next==null&&n!=0)//判断cur1是不是最后一个点,如果是说明要删除的点是链表的第一个点{head=head.next;return head;}}while(cur1.next!=null){cur1=cur1.next;cur2=cur2.next;}//经过上面这个while循环 cur1跑到了最后一个节点 cur2跑到了要删除节点的前一个if(n==1){cur2.next=null;}else {cur2.next=cur2.next.next;}return head;}


0 0
原创粉丝点击