我的思路:
递归至链表尾,然后向前增加至n,然后删除该结点。后面发现没那么简单。
我刚开始写的程序如下:
当我检测n在栈中的值我发现用print函数后n输出都是9,我想起函数每次调用都会将n值存入栈而这个值是不变的,例如n=10,出栈后n=9,每个出栈的n都等于9
然后我看leetcode上有个人思路跟我的一样,然而他用了一个helper函数
public ListNode deleteNth(ListNode head,int n){
if(head==null||head.next==null) return head;
deleteNth(head.next,n);
n--;
if(n==0)head = head.next;
return head;
}
<img src="https://img-blog.youkuaiyun.com/20151227152814401?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="400" height="300" alt="" />
</pre><pre name="code" class="java"><pre name=<span style="font-family: Arial, Helvetica, sans-serif;">"code" class="java"> public class Solution{</span>
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode cur = head;
int count = helper(cur, 0, n);
if (count+1 == n) head = head.next;//删除头节点此时头节点的索引count=n-1
return head;
}
public int helper(ListNode head, int count, int target) {
if (head == null || head.next == null) {
return 0;
}
count = helper(head.next, count, target);//这里count保存的值会递增,因为值是在函数递归完成后将值赋给count
count++;
if (count == target) { //0<count<n
head = head.next;
head.next = head.next.next;//删除非头节点结点
}
return count;
}
}
循环思路:
设计两个指针p1,p2然后使p1往前指向第n+1个结点(因为p2最后指向null而不是最后一个节点),如果p1这时为空,说明n大于等于链表长度,此时应当删除头节点!如果不是,就同时将两指针向后移动,直到p1==null时,此时p2指向离最后一个结点n+1处,删除指定节点只需要:p2.next = p2.next.next!!(因为p2 = p2.next无法删除结点)
代码如下:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode reverseList(ListNode head) {
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution{
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode p1 = head,p2 = head;
while(n-->0){
p1 = p1.next;
}
if(p1==null)return head.next;
p1 = p1.next;
while(p1!=null){
p1 = p1.next;
p2 = p2.next;
}
p2.next = p2.next.next;
return head;
}
}