41.Remove Nth Node From End of List

Given a linked list, remove the nth node from the end of list and return its head.(Difficulty: Easy

For example,

   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.

分析:这个题目是典型的链表删除元素操作。关键在于1,正确找到被删除的元素;2,避免链表断掉。

方法一:遍历了两边链表。

/* 这是我做的第1个方法,实现这个地方相当于遍历了两遍链表
	 * 第一遍:统计链表有多少个元素
	 * 第二遍:从头遍历找到需要被删除的元素
	 * 在第一次实现的时候我是把删除的节点为头结点时做了特殊处理,直接返回head.next
	 */
	public ListNode removeNthFromEnd1(ListNode head, int n) {
		ListNode q = head;
		ListNode p = q.next;
		int total = 1;// 记录链表中的总元素个数
		while (p != null) {
			q = p;
			p = p.next;
			total++;
		}

		if (n == total) {// 即要删的是头结点
			return head.next;
		}

		// 出while循环的时候q是链表的最后一个元素
		p = head;
		System.out.println("total = " + total);
		for (int i = 1; i < total - n + 1; i++) {
			q = p;
			p = p.next;// 永远保持q在p的前一个
		}
		// 出来for循环之后,p是应该被删的元素
		System.out.println("被删的元素 " + p.val);
		q.next = p.next;

		return head;
	}</span>

方法二:对方法一做了一点点修改。

</* 加上一个额外的头结点dump,这样在删除的节点是head时不需要再做额外的处理。
	 */
	public ListNode removeNthFromEnd2(ListNode head, int n) {
		ListNode p = head.next;
		int total = 1;// 记录链表中的总元素个数
		while (p != null) {
			p = p.next;
			total++;
		}

		ListNode dump = new ListNode(0);//做为额外的头节点
		dump.next = head;
		ListNode q = dump;
		p = head;  //保持q在p的前一个
		
		System.out.println("total = " + total);
		for (int i = 1; i < total - n + 1 ; i++) {
			q=p;
			p = p.next;// 永远保持q在p的前一个
		}
		// 出来for循环之后,p是应该被删的元素
		q.next = p.next;
		
		return dump.next;
	}

方法三:最符合题意,让链表只走了一遍。

Step1:加上dump做为额外的头节点,最后返回dump.next;

Step2:先让first走n步;(敢在题目直接让first走n步是因为note中提到输入的n都是合法的)

Step3:再让first和p同时走,这样当first走到链表结尾时,p就是被删除的节点,在走的过程中 节点q永远是p的前一个节点;

Step4:删除p节点。

/*效率最快,只走了一遍链表即可*/
	public ListNode removeNthFromEnd3(ListNode head, int n) {
		/*Step1:加上dump做为额外的头节点,最后返回dump.next*/
		ListNode dump = new ListNode(0);
		dump.next = head;
		
		ListNode first = head;
		ListNode p = head;
		ListNode q = dump;//永远保持q在p的前一个
		
		/*Step2:先让first走n步*/
		for(int i = 0;i<n;i++){
			first = first.next;
		}
		
		/*Step3:再让first和p同时走,这样当first走到链表结尾时,p就是被删除的节点,在走的过程中
		 * 节点q永远是p的前一个节点*/
		while(first!=null){
			first = first.next;
			q=p;
			p=p.next;
		}
		/*Step4:删除p节点*/
		q.next = p.next;
		
		return dump.next;
	}

总结:做链表的题目一定要保证不能出现空指针的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值