IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> leetcode 链表的回文和相交 -> 正文阅读

[数据结构与算法]leetcode 链表的回文和相交

1. 链表的回文结构

1.1 题目描述

牛客网把这道题标成了难题,然后leetcode标成了简单

题目链接

image-20211107201637064

提示和进阶要求:

image-20211107201806319

1.1.1 接口函数

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


bool isPalindrome(struct ListNode* head){
}

1.2 大致框架

思路一:

强盗法:开一个足够大的数组,把链表的数据存到数组里面,通过数组将进行判断是否是回文的

但是空间复杂度是O(N),不符合要求

下面看一个可行的一般思路

1.2.1 思路分析

  1. 快慢指针找到中间节点先找到中间节点
    image-20211107205628764
  2. 后半部分逆置
    image-20211107211506298
  3. 再比较

这样的想法正好就是之前做过的两道题目的结合,一道是找中间节点,还有一个是反转链表

点链接可以传送,回顾之前的题目

leetcode 双指针方法解两道题

leetcode 206.反转链表

1.2.2 具体步骤

稍微结合一下两道题的方法就可以了

注意在开始之前要考虑极限情况 当只有一个节点和两个节点的时候正好是回文

if (head == NULL || head->next == NULL)
			return true;

判断是否回文部分

其实当我们输入的情况是偶数个时,第n/2-1个节点是指向中间节点的,而中间节点正好指向NULL,所以恰好不用对第n/2-1个节点指向空,依旧正常判断是否链表是否回文

while (head && prev)
		{
			if (head->val != prev->val)
				return false;
			head = head->next;
			prev = prev->next;
		}
		return true;

image-20211107222602555

小结:

当然这道题在反转链表的时候可以选择头插法或者三指针逆置法或者递归法

1.3 具体实现

bool isPalindrome(struct ListNode* head) {
	if (head == NULL || head->next == NULL)
		return true;
	struct ListNode* slow, * fast, * prev, * cur, * next;
	slow = fast = head;

	//找到中间节点
	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;
	}
	prev = NULL;
	cur = slow;
    next=cur->next;
	//后半部分逆置
	while (cur)
	{
		cur->next = prev;
		prev = cur;
		cur = next;
        if (next)
    	{
		    next = next->next;
	    }
	}
	//逐点比对
	while (head && prev)
	{
		if (head->val != prev->val)
			return false;
		head = head->next;
		prev = prev->next;
	}
	return true;
}

image-20211107225527898

2. 相交链表

2.1 题目描述

题目链接

image-20211107204409636

给出示例:

image-20211107204537920

提示与进阶

image-20211107204601936

2.1.1 接口函数

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    
}

2.2 大致框架

2.2.1 思路分析

先要搞清楚本题的概念是:一个链表节点里面不可能有两个指针

image-20211108102133300

找一个好方法判断相交

  • 只要判断链表的最后一个节的尾指针是否相同即可,当然也不能比较节点的值,一定要比较指针

所以我们要找到指针

  1. 计算出两个链表的节点数之差x
  2. 长链表指针先走x个
  3. 再同时往前走,第一个相同的节点就是两个链表的交点

2.2.2 具体步骤

先求AB链表的长度

    int lenA=0;
    int lenB=0;
    while(curA->next)//走到最后一个节点,不要走到空
    {
        curA=curA->next;
        lenA++;
    }
        while(curB->next)
    {
        curB=curB->next;
        lenB++;
    }

看到cur->next就得想到要在开头先判一下空

由一个为空肯定不相交,直接返回NULL

 //判空
    if(headA==NULL||headB==NULL)
    {
        return NULL;
    }

判断相等不相等,不相等必不相交

   if(curA!=curB)
    {
        return NULL;
    }

找出长的和差距数

    struct ListNode* longList=headA,*shortList=headB;
    if(lenB>lenA)
    {
        longList=headB;
        shortList=headA;
    }
    int gap=abs(lenB-lenA);

最后一起往前走,找到一样的点就返回任意一个即可

  while(gap--)
    {
        longList=longList->next;
    }
    while(longList!=shortList)
    {
            longList=longList->next;
            shortList=shortList->next;    
    }
    return longList;

2.3 具体实现

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    //判空
    if(headA==NULL||headB==NULL)
    {
        return NULL;
    }
    struct ListNode*curA=headA, *curB=headB;
    int lenA=0;
    int lenB=0;
    while(curA->next)//走到最后一个节点,不要走到空
    {
        curA=curA->next;
        lenA++;
    }
        while(curB->next)
    {
        curB=curB->next;
        lenB++;
    }
    if(curA!=curB)
    {
        return NULL;
    }
    //长的先走差距数,再一起走
    struct ListNode* longList=headA,*shortList=headB;
    if(lenB>lenA)
    {
        longList=headB;
        shortList=headA;
    }
    int gap=abs(lenB-lenA);
    while(gap--)
    {
        longList=longList->next;
    }
    while(longList!=shortList)
    {
            longList=longList->next;
            shortList=shortList->next;    
    }
    return longList;
}

image-20211108110832880

小结:

这次的两道题目总的来说难度比上次高一点,像是综合一点的题型,主要好好思考好思路怎么实现,本质上来说代码难度并不是很高,还是需要多理解,多体会单链表

如果觉得有收获的话,希望大家一键三连

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-09 19:49:07  更:2021-11-09 19:50:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/9 1:52:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码