問題描述: 給你一個單向鏈表,刪除鏈表倒數第n個結點,而後返回head結點。這裏的數字n是有效數字。node
Given linked list: 1->2->3->4->5, and n = 2.
移除倒數第二個結點以後: 1->2->3->5.
複製代碼
方法一:先遍歷獲取鏈表長度,接着獲取要移除的前一個元素,修改該元素的node.next --> node.next.next。 git
代碼以下:github
/**
* 移除鏈表倒數第n個結點,先遍歷獲取鏈表長度,接着獲取要移除的前一個元素,修改該元素的node.next --> node.next.next。
*
* @param head
* @param n
* @return
*/
public SingleNode removeNthFromEnd1(SingleNode head, int n) {
SingleNode dummy = new SingleNode(0, head);
//獲取鏈表長度
int length = 0;
SingleNode first = head;
while (first != null) {
length++;
first = first.next;
}
// 找到角標爲(length - n - 1)的結點,讓其next指向下下一個結點。
first = head;
int index = 0;
while (index < length - n - 1) {
first = first.next;
index++;
}
first.next = first.next.next;
return dummy.next;
}
複製代碼
測試代碼以下:bash
SingleLinkedList sll = new SingleLinkedList();
for (int i = 0; i < 5; i++) {
sll.addLast(i + 1);
}
System.out.println(sll.toString());
SingleNode node1 = removeNthFromEnd1(sll.getFirst(), 2);
sll.logFromHead("removeNthFromEnd1", node1);
複製代碼
輸出結果以下:符合預期測試
I/System.out: SingleLinkedList:[1, 2, 3, 4, 5]
I/System.out: removeNthFromEnd1:[1, 2, 3, 5]
複製代碼
感興趣的同窗可自行修改測試用例。ui
方法二:使用兩個指針,兩個指針保持固定間距n+1,接着開始遍歷。當前面的指針指向null的時候,後面的那個指針恰好指向要移除的結點前一個,咱們讓其next指向其next.next便可。 spa
/**
* 移除鏈表倒數第n個結點,使用兩個指針實現。
*
* @param head
* @param n
* @return
*/
public SingleNode removeNthFromEnd2(SingleNode head, int n) {
SingleNode dummy = new SingleNode(0, head);
SingleNode left = dummy;
SingleNode right = dummy;
for (int i = 0; i <= n; i++) {
right = right.next;
}
while (right != null) {
left = left.next;
right = right.next;
}
left.next = left.next.next;
return dummy.next;
}
複製代碼
測試代碼以下:.net
SingleLinkedList sll = new SingleLinkedList();
for (int i = 0; i < 5; i++) {
sll.addLast(i + 1);
}
System.out.println(sll.toString());
SingleNode node2 = removeNthFromEnd2(sll.getFirst(), 2);
sll.logFromHead("removeNthFromEnd2", node2);
複製代碼
輸出結果以下:跟預期一致。指針
SingleLinkedList:[1, 2, 3, 4, 5]
removeNthFromEnd2:[1, 2, 3, 5]
複製代碼
項目中搜索SingleLinkedList便可。code
github傳送門 github.com/tinyvampire…
gitee傳送門 gitee.com/tinytongton…