給定一個鏈表,刪除鏈表的倒數第 n 個節點,並且返回鏈表的頭結點。
示例:給定一個鏈表: 1->2->3->4->5, 和 n = 2.當刪除了倒數第二個節點後,鏈表變爲 1->2->3->5.
說明:給定的 n 保證是有效的。
進階:你能嘗試使用一趟掃描實現嗎?
拿到這一題有兩個思路,
第一個思路:因爲是要刪除倒數第幾個鏈表節點,所以我們需要知道鏈表的長度,我們如果知道鏈表的長度的話可以非常方便的找到最後要刪除的,然後將其刪除。需要兩遍遍歷
第二個思路就是用雙指針法,一個左指針,一個右指針,首先進行將右指針和左指針的距離,給拉長至n的長度,那麼當我們的右指針指到最後一個節點的時候,左指針也就找到了倒數第幾個節點,我們就可以進行刪除啦。只需要一遍遍歷
package medium;
public class deleteN {
public ListNode removeNthFromEnd(ListNode head, int n) {
if(head.next==null||head==null){
return null;
}
int len=1;
ListNode h1=head;
while(h1.next!=null){
len++;
h1=h1.next;
}
System.out.println(len);
ListNode h2=new ListNode(0);
h1=h2;
h2.next=head;
while(len-n>0){
h2=h2.next;
len--;
}
h2.next=h2.next.next;
return h1.next;
}
public ListNode removeNthFromEnd2(ListNode head, int n) {
ListNode dummy=new ListNode(0);
dummy.next=head;
ListNode left=dummy;
ListNode right=dummy;//雙指針法
for(int i=0;i<n+1;i++){
right=right.next;
}
while(right!=null){
right=right.next;
left=left.next;
}
left.next=left.next.next;
return dummy.next;
}
public static void main(String[] args) {
// TODO 自動生成的方法存根
ListNode l1=new ListNode(1);
ListNode l2=new ListNode(2);
ListNode l3=new ListNode(3);
l1.next=l2;
l2.next=l3;
deleteN d=new deleteN();
ListNode ln=d.removeNthFromEnd2(l1, 3);
while(ln != null){
System.out.println(ln.val);
ln=ln.next;
}
}
}