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

这篇具有很好参考价值的文章主要介绍了算法通关村第二关——指定区间反转问题解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

指定区间反转:

Leetcode92有这样一道题:给你单链表的头指针head和两个整数left、right,其中left<=right,请你反转从位置left到位置right的链表结点,返回反转后的链表,如图所示:

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

这道题呢,有两种不同的解法,分别是头插法和穿针引线法,头插法就是我们前面说过的带头结点的反转,而穿针引线法就是不带头结点实现反转的方法,接下来我将逐一介绍:

1.头插法: 

前面我们说过带头结点的反转有两个重点要求:1.虚拟头结点  2.拆拆拆

熟练掌握以上两个思想后,这道题的解决将变得十分简单。在这道题中,我认为我们可以将区间前的第一个结点看作虚拟头结点,而区间内除第一个结点以外的全部结点则需要逐一拆除并进行插入,如下图所示:

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

我们可以建立一个cur指针始终指向区间的第一个元素,之后的每一步操作我们需要以下几个步骤:1.找到当前结点的下一个结点 2.拆除:令cur指针指向的结点指向next结点的下一个结点(即:将next指针指向的结点“拆下”,并保存后一个结点的位置)3.插入: 令next指针指向的结点指向虚拟头结点的下一个结点(这里的虚拟头结点就是我们说的区间前的第一个结点) 4:令虚拟头结点指向next指针所指向的结点。重复上述操作,即可实现区间反转,代码如下:

// 头插法
struct ListNode* reverseBetween(struct ListNode* head, int left, int right)
{
	struct ListNode* dummy = (struct ListNode*)malloc(sizeof(struct ListNode));//开辟一个虚拟的头结点
	dummy->val = -1;
	dummy->next = head;//令虚拟头结点的下一个结点指向真实头结点
	struct ListNode* ans = dummy;//创建一个指针用来遍历链表
	for (int i = 0; i < left - 1; i++)
	{
		ans = ans->next; //找到指定区间的前一个元素
	}
	struct ListNode* cur = (struct ListNode*)malloc(sizeof(struct ListNode));
	cur = ans->next;//令cur为区间的第一个结点,并始终保持不变
	for (int i = 0; i < right - left; i++)//遍历整个区间
	{
		struct ListNode* next = cur->next;//首先找到当前结点的下一个结点
		cur->next = next->next;//令当前结点的下一个结点指向下一个结点所指向的结点,即将next结点“拆下”
		next->next = ans->next;//令next结点的下一个结点指向区间前的结点所指向的结点
		ans->next = next;//令区间前的结点指向next结点
	}
	return dummy->next;
}

2.穿针引线法:

如果说第一种方法的特点是拆拆拆,那这一种方法的特点就类似于从整体上解决问题的方法,让我们先从图片中了解大致思想:

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

 

这种方法呢,其实就是将整个区间先与原链表脱离,单独将区间反转之后再接入原链表,步骤如下:1.找到区间的前驱结点与后续结点,便于之后进行连接 2.定位区间的左结点与右结点 3.将整个区间拆下 4.对区间进行反转 5.将反转后的区间接入旧链表,代码如下:文章来源地址https://www.toymoban.com/news/detail-620587.html

//反转链表
void reverseList(strruct ListNode* head)
{
	sturct ListNode* pre = NULL;
	struct ListNode* cur = head;
	while (cur != NULL)
	{
		struct ListNode* next = cur->next;
		cur->next = pre;
		pre = cur;
		cur = next;
	}

}
//穿针引线法
struct ListNode* reverseBetween(struct ListNode* head, int left, int right)
{
	struct ListNode* dummy = (struct ListNode*)malloc(sizeof(struct ListNode));
	dummy->val = -1;
	dummy->next = head;
	struct ListNode* pre = dummy;
	for (int i = 0; i < left - 1; i++)
	{
		pre = pre->next;//首先找到区间的前一个结点
	}
	struct ListNode* rightNode = pre;
	for (int i = 0; i < right - left + 1; i++)
	{
		rightNode = rightNode->next;//令该结点指向区间的最后一个结点
	}
	struct ListNode* leftNode = pre->next;//找到区间的第一个结点
	struct ListNode* succ = rithtNode->next;//找到区间之后的第一个结点
	rightNode->next = NULL;
	pre->next = NULL;//断开区间链表与原链表的链接
	reverseList(leftNode);//将区间内的链表进行反转
	pre->next = rightNode;//令之前保存的区间前的第一个结点指向此时链表的头结点
	leftNode->next = succ;//令链表的尾结点指向之前保存的区间之后的第一个结点
	return dummy->next;
}

到了这里,关于算法通关村第二关——指定区间反转问题解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法通关村第二关——终于学会链表反转了

     方法一:建立虚拟头结点辅助反转 创建一个虚拟头节点,获取链表中每个节点,用虚拟头节点指向这个节点,并在链表中删除, 方法二:直接操作链表实现反转 记录当前节点(cur),前驱节点(pre),后继节点(next),先将当前节点的下一个节点指向前驱节点,然后将当前节点赋给前

    2024年02月14日
    浏览(37)
  • [Go版]算法通关村第二关——终于学会链表反转了

    题目链接:LeetCode-206. 反转链表 源码地址:GitHub-golang版本 说明:遍历该链表,依次取出当前节点插入到新链表的首位(虚拟头结点紧后)即可, 注意要提前保存当前节点的Next数据 ,否则插入到新链表后就没法继续向下遍历了。 说明:原理和方法1一致,只不过现在没有虚拟

    2024年02月14日
    浏览(32)
  • [Go版]算法通关村第二关青铜——终于学会链表反转了

    题目链接:LeetCode-206. 反转链表 源码地址:GitHub-golang版本 说明:遍历该链表,依次取出当前节点插入到新链表的首位(虚拟头结点紧后)即可, 注意要提前保存当前节点的Next数据 ,否则插入到新链表后就没法继续向下遍历了。 说明:原理和方法1一致,只不过现在没有虚拟

    2024年02月13日
    浏览(24)
  • 算法通关村第二关——单链表加一

    LeetCode369 用一个非空单链表来表示一个非负整数,然后将这个整数加一。你可以假设这个整数除了 0 本身,没有任何前导的 0.这个证书的各个数位按照 高位在链表头部、低位在链表尾部 的顺序排列。 计算是从低位开始的,而链表是从高位开始的,所以要处理就必须反转过来

    2024年02月14日
    浏览(32)
  • 算法通关村第二关——终于学会链表

    LeetCode206 给我们单链表的头结点head,请你反转链表,并返回反转后的链表,如图所示: 本题有两种方法,分别为 建立虚拟头结点辅助反转 以及 直接操作链表实现反转 ,两种方法我将逐一分析讲解。 首先从名字分析一下这种方法,虚拟头结点,顾名思义,我们可以建立一个

    2024年02月15日
    浏览(33)
  • 算法村第二关(1)——手写链表反转

    题目:Leetcode-206. 反转链表 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表 对于链表反转的问题,想起来其实非常简单。 就是从前往后,将节点一个一个采用头插法的做成一个新链表嘛,这样新链表就是旧链表的反转链表啦! 那既然这么简单,为什么还要学

    2024年02月14日
    浏览(28)
  • 算法通过村第二关-链表黄金笔记|K个一组反转

    提示:没有人天生就喜欢一种气味而讨厌另一种气味。文明的暗示而已。 给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。 k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

    2024年02月14日
    浏览(29)
  • 算法通关村十二关 | 字符串前缀问题

    题目:LeetCode14,14. 最长公共前缀 - 力扣(LeetCode) 我们先看公共前缀有什么特点。 第一种方式,竖着比较,如图左边所示,选取数组中第一个字符串的位置,每前进一个就比较各个字符串,看是否相等,只有某一轮遇到不相等,则结束返回结果。 还是这张图         如

    2024年02月11日
    浏览(37)
  • 算法通关村第十二关——不简单的字符串转换问题

    字符串是我们在日常开发中最常处理的数据,虽然它本身不是一种数据结构,但是由于其可以包含所有信息,所以通常作为数据的一种形式出现,由于不同语言创建和管理字符串的方式也各有差异,因此针对不同语言特征又产生了很多问题。 常见的字符串转换题目,也就是在

    2024年02月10日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包