算法村通关第二关——单链表指定区间反转问题解析

单链表指定区间反转

力扣92题,给定单链表的头指针head,和两个整数leftright,其中left <= right.反转从位置leftright的链表结点,并返回反转后的链表。

用两种较好的方法来解决这道题,一种是不带虚拟头结点的方法叫做穿针引线法,另外一种是用到虚拟头结点的方法叫做头插法。

1.头插法

反转的整体思想:是在需要反转的区间里,每遍历到一个结点,让这个新节点来到反转部分的起始位置。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DejXtV8e-1690549641475)在这里插入图片描述

每走一步都需要考虑结点指针怎么指,既要将结点摘下来接到对应的位置上,还需要保证后续结点能够找到。从左边边界点的前一个结点开始进行反转,每次将当前结点插入到反转链表的起始位置。

在这里插入图片描述

var reverseBetween = function(head, left, right) {
    // 如果链表只有一个元素,返回头结点即可
	if (!head || !head.next) return head;

	const dummyHead = new ListNode(-1);
	dummyHead.next = head;
	let previousNode = dummyHead;
	// 从左边边界点的前一个结点开始进行反转
	for (let i = 0; i < left - 1; i++) {
		previousNode = previousNode.next;
	}

	let currentNode = previousNode.next;
	for (let i = 0; i < right - left; i++) {
		const nextNode = currentNode.next;
		currentNode.next = nextNode.next;
		nextNode.next = previousNode.next;
		previousNode.next = nextNode;
	} 
	return dummyHead.next;
}

2.穿针引线法

指定区间反转的穿针引线算法可以复用链表反转算法,反转流程如图所示。

在这里插入图片描述

  1. )得到反转区间链表
  2. )切断链接,使反转区间链表成为一个独立链表
  3. )将反转区间链表进行反转重新接回原链表中,最后返回最终链表
// 穿针引线法
var reverseBetween = function(head, left, right) {
	if (!head || !head.next) return head;

	const dummyHead = new ListNode(-1);
	dummyHead.next = head;
	let previousNode = dummyHead;

	// 第一步,找到反转区间左边界结点的前一个结点
	for (var i = left - 1; i > 0; i--) {
		previousNode = previousNode.next;
	}
	// 第二步,找到反转区间右边界结点
	let rightEdgeNode = previousNode;
	for (var i = right - left + 1; i > 0; i--) {
		rightEdgeNode = previousNode.next;
	}

	// 第三步,得到反转区间链表
	let leftEdgeNode = previousNode.next;
	let currentNode = rightEdgeNode.next;
	// 第四步,切断链接,使反转区间链表成为一个独立链表
	previousNode.next = rightEdgeNode.next = null;

	// 第五步,将反转区间链表进行反转
	reverseLinkedList(leftEdgeNode);

	// 第六步,将反转后的链表重新接回原链表中并返回最终链表
	previousNode.next = rightEdgeNode;
	leftEdgeNode.next = currentNode;
	return dummyHead.next;
}

// 迭代法反转链表
const reverseLinkedList(head) {
	let previousNode = null;
	let currentNode = head;

	while (currentNode) {
		const nextNode = currentNode.next;
		currentNode.next = previousNode;
		previousNode = currentNode;
		currentNode = nextNode;
	}
}

总结

在进行反转的过程中,难点就是想清楚结点指针该怎么变化,搞清楚这点,反转就容易理解了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值