力扣初级算法-18-链表-删除链表的倒数第N个节点

学习目标:

本次学习目标为 力扣初级算法-链表,其中主要的LC如下:

  • 删除链表的倒数第N个节点

学习内容:

  1. 删除链表的倒数第N个节点 -----(链接
    给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
    示例1:
    输入:head = [1,2,3,4,5], n = 2
    输出:[1,2,3,5]

示例2:
输入:head = [1], n = 1
输出:[]

示例3:
输入:head = [1,2], n = 1
输出:[1]

说明:
链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz

解题思路:

  • 解法一: 常规解法

  • 边界问题:删除位大于入参的链表的长度 或者直接删除首结点的情况

  • 代码逻辑过程:

    • 声明 pre 变量作为需要删除的前一个结点
    • 然后循环算出当前链表的长度 length
    • 判断链表长度 length 与入参n 的关系,当 n > length 时,直接返回 入参head (相当于不做删除)
    • 定位需要删除的节点位置-- 删除的节点位 last 等于 length - n,(这里解释下,正常下 last + n = length,此时做等式变换,即可知道我们需要删除的节点位 last = length - n)
    • 接下来是替换删除位,将删除节点的上一个节点的 next 指向 删除节点的next。
  • 代码实现:


	/***
	 *  解法一 常规解法
	 */
	public ListNode removeNthFromEnd01(ListNode head, int n) {
		// 边界条件: 删除位大于入参的链表的长度 或者直接删除首结点的情况

		// 作为要删除结点的前一个结点
		ListNode pre = head;

		// 先循环算出链表的长度
		int length = getLength(head);

		if (n > length){
			return head;
		}

		// 要删结点
		int last = length - n;
		if (0 == last){
			return head.next;
		}

		// 循环遍历需要删除的节点对象
		for (int i = 0; i < last - 1 ; i++) {
			pre =pre.next;
		}

		// 将删除节点的前节点的 next 指向删除节点的下一节点
		pre.next = pre.next.next;
		return head;

	}
	private int getLength(ListNode head) {
		int len = 0;
		while (head != null) {
			len++;
			head = head.next;
		}
		return len;
	}

解题思路:

  • 解法二: 双指针解法

  • 边界问题:删除位大于入参的链表的长度 或者直接删除首结点的情况

  • 代码逻辑过程:

    • 声明两个指针,分别作为 快、慢指针对应的节点: fastNode 、 slowNode
    • 基于删除位 last 与 入参的倒数数 n 的关系,我们可以知道 last + n = length,但是当前解法不依赖于链表长度,故我们可以先循环 入参 n 次查找 fastNode 的next,将 fastNode 往后移动,当 fastNode 一直往后移动到 fastNode 不为 null 的情况,相当于遍历得到了 入参 head 的链表长度了,此时,在遍历到 n 点后, slowNode 慢指针节点也可是 slowNode = slowNode.next,slowNode 也就相当于 要删除的节点位 last 了。
  • 代码实现:

/***
	 *  解法二: 双指针解法
	 */
	public ListNode removeNthFromEnd02(ListNode head, int n) {
		ListNode fastNode = head ;
		ListNode slowNode = head;


		// 边界条件: 删除位大于入参的链表的长度 或者直接删除首结点的情况
		for (int i = 0; i < n; i++) {
			fastNode = fastNode.next;
		}

		// 如果遍历 n次后返回的是null,则 n已大于 链表的长度
		if (null == fastNode ){
			return head.next;
		}

		// 由于前面 fast 已迁移至第N位, 则需要删除的位置是 length - n ,此时通过 慢指针 slowNode 前移
		// slowNode 到的点,即为要删除的链表节点
		while (null != fastNode ){
			fastNode = fastNode.next;
			slowNode = slowNode.next;
		}
		slowNode.next = slowNode.next.next;

		return head;

	}
	private int getLength(ListNode head) {
		int len = 0;
		while (head != null) {
			len++;
			head = head.next;
		}
		return len;
	}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值