leetcode-19-删除链表的倒数第N个节点(remove nth node from end of list)-java

题目及用例及linklist

package pid019;


public class LinkList {
	public class ListNode {
  	  public int val;
  	  public ListNode next;
  	  ListNode(int x) 
  	  { val = x; 
  	  	next=null;
  	  }
	}
	
	ListNode first;
	
	public LinkList(int x){
		first=new ListNode(x);
		first.next=null;
	}
	
	public void addLast(int x){
		ListNode a=first;
		while(a.next!=null){
			a=a.next;
		}
		ListNode b=new ListNode(x);
		a.next=b;
	}
	
	public void printList(){
		ListNode a=first;
		System.out.println("print listnode");
		while(a!=null){//直到最后一个不为空的节点
			System.out.print(a.val+"  ");
			a=a.next;
		}
		System.out.println();
	}
	
	
	
}

package pid019;
/* 删除链表的倒数第N个节点

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

说明:

给定的 n 保证是有效的。

进阶:

你能尝试使用一趟扫描实现吗?



*/


import pid019.LinkList;
import pid019.LinkList.ListNode;

public class main {
	
	
	public static void main(String[] args) {
		
		LinkList a=new LinkList(1);
		a.addLast(2);
		a.addLast(5);
		a.addLast(15);
		
		LinkList b=new LinkList(-5);
		b.addLast(0);
		b.addLast(500);
		b.addLast(-100);
		
		a.printList();
		test(a.first,2);
		a.printList();
		
		b.printList();
		test(b.first,4);
		b.printList();
	}
		 
	private static void test(ListNode ito,int ito2) {
		Solution solution = new Solution();
		String rtn;
		long begin = System.currentTimeMillis();
		System.out.println();
		//开始时打印数组
		
		solution.removeNthFromEnd(ito,ito2);//执行程序
		long end = System.currentTimeMillis();	
		
		//System.out.println(":rtn" );
		//System.out.print(rtn);
		System.out.println();
		System.out.println("耗时:" + (end - begin) + "ms");
		System.out.println("-------------------");
	}

}

解法1(成功,11ms,很快)
先得到链表长度,再根据长度,从头开始减去节点,具体在解法中

package pid019;

import pid019.LinkList.*;
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        int length=0;
        ListNode a=head;
        ListNode temp;
        while(a!=null){
        	length++;
        	a=a.next;
        }
        //比如5个,倒数第二就为第4个,为第三个与第五个相连,如果不是去掉第一个,为(length-n)  (length-n).nex.next 相连
        //如果是第一个,如果只有一个,返回null,否则将head的值改为下一个,next改为head.next.next
        if(length==n){
        	if(length==1){//去掉只有一个的第一个
        		return null;
        	}
        	else{//去掉第一个
        		head.val=head.next.val;
        		temp=head.next;
        		head.next=temp.next;
        		temp.next=null;
        		return head;
        	}
        }
        else{
        	int i=1;
        	a=head;
        	while(i<length-n){
        		a=a.next;
        		i++;
        	}
        	temp=a.next;
        	a.next=temp.next;
        	temp.next=null;
        	return head;
        	
        }
    	
    }
}

解法二(成功,2ms,超快)
速度其实一样快,都是走length+n步,但看上去简洁了很多
双指针算法

先让一个指针走n-1步,然后再让一个指针指向头结点,然后两具指针一起走,直到前一个指针的next=null,后一个指针就是倒数第N个结点,删除倒数第N个结点就可以了。
 如何删除,确定begin前的一个节点pre,让pre.next=begin.next即可
在这里插入图片描述

	public ListNode removeNthFromEnd(ListNode head, int n) {
		//双指针,后走的
		ListNode begin=head;
		///双指针,先走的
		ListNode end=head;
		//begin之前的node
		ListNode pre=null;
		//很明显,如果只有2个,n=1,end走1步时,end.next=null,此时的begin就是被删除的
		for(int i=0;i<n-1;i++){
			//end先走n-1步
			end=end.next;
		}
		//直到end.next=null,此时的begin就是被删除的
		while(end.next!=null){
			end=end.next;
			pre=begin;
			begin=begin.next;
		}
		if(begin==head){
			//删除头结点,直接返回next即可
			return head.next;
		}
		//普通情况
		pre.next=begin.next;       				
		return head;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值