Given a linked list, remove the nth node from the end of list and return its head.
For example,java
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.
Note:
Given n will always be valid.
Try to do this in one pass.node
刪除單鏈表的倒數第N個結點,注意:輸入的N都是合法,在一次遍歷中完成操做。算法
先讓一個指針走找到第N個節點,而後再讓一個指針指向頭結點,而後兩具指針一塊兒走,直到前一個指針直到了末尾,後一個指針就是倒數第N+1個結點,刪除倒數第N個結點就能夠了。測試
鏈表結點類this
public class ListNode { int val; ListNode next; ListNode(int x) { val = x; next = null; } }
算法實現類spa
public class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode pa = head; ListNode pb = head; // 找到第n個結點 for (int i = 0; i < n && pa != null; i++) { pa = pa.next; } if (pa == null) { head = head.next; return head; } // pb與pa相差n-1個結點 // 當pa.next爲null,pb在倒數第n+1個位置 while (pa.next != null) { pa = pa.next; pb = pb.next; } pb.next = pb.next.next; return head; } }
第一種方式:
1.首先判斷K值和鏈表是否爲空,若是k<=0,或鏈表爲空,直接返回head;
2.知足上面條件後,定義ListNode P=head,重頭開始遍歷鏈表,走k步後,退出循環(在此循環中,若是沒到K不p就爲null了,說明沒有倒數第K個節點,k大於表長度了,直接返回head)。
3.定義ListNode q = head,與p同步向後走,直到p的next爲空時候,節點爲要刪除節點的前一個結點。.net
第二種方式:
1.首先判斷K值和鏈表是否爲空,若是k<=0,或鏈表爲空,直接返回head;
2.遍歷一遍鏈表,每走一步,讓k值減1.
3.遍歷完後,若是k大於零,說明k大於鏈表長度,直接返回head;若是k等於0,要刪除的節點就是頭結點,直接返回head.next;若是k小於0時候第4步。
4.定義q=head,重新遍歷節點,每走一步k加1,直到k=0時候,退出循環,此時q的下一個節點就是要刪除的節點。指針
(4.解析:在這部分,爲何這樣作,可能不是很容易理解,給你們舉個例子,假如如今有一鏈表有8個節點,k=3.那麼,前三步後,k=-5。你們想想,k等於三是要刪除倒數第3個節點,咱們只要從頭走5步就能夠到達刪除節點的前一個節點了,爲啥是5,由於8 = 3+5。說道這裏不知道你明白沒有。)code
package bjtu.edu.cn1; public class ListNodeTest { // 2.在單鏈表中刪除倒數第k個節點(方法一) public static ListNode removeLastKthNode(ListNode head, int k) { if (k <= 0 || head == null) return head; ListNode p = head; for (int i = 0; i < k; i++) { if (p.nextNode != null) p = p.nextNode; else return head; } ListNode q = head; while (p.nextNode != null) { p = p.nextNode; q = q.nextNode; } q.nextNode = q.nextNode.nextNode; return head; } // 2.在單鏈表中刪除倒數第k個節點(方法二) public static ListNode removeLastKthNode2(ListNode head, int k) { if(k <= 0 ||head == null)return head; ListNode p = head; while(p!=null){ p = p.nextNode; k--; } if(k==0)return head.nextNode; if(k<0){ ListNode q = head; while(++k!=0){ //這裏注意,先自加,在判斷 q=q.nextNode; } q.nextNode=q.nextNode.nextNode; } return head; } // 建立鏈表 public static ListNode creatListNode(int data[]) { ListNode head = new ListNode (data[0]); ListNode temp = head; for (int i = 1; i < data.length; i++) { ListNode headNext = new ListNode(data[i]); temp.nextNode = headNext; temp = temp.nextNode; } return head; } // 測試個方法 public static void main(String[] args) { int[] data1 = { 1, 2, 4, 5, 6, 7 }; ListNode head1 = creatListNode(data1); //在單鏈表中刪除倒數第k個節點 ListNode head = removeLastKthNode2(head1, 1); while (head != null) { System.out.println(head.values); head = head.nextNode; } } } // 鏈表節點類 class ListNode { public int values; public ListNode nextNode; public ListNode(int data) { this.values = data; } }