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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 链表面试题 -> 正文阅读

[数据结构与算法]链表面试题

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param head ListNode类 the head
     * @return bool布尔型
     */
    //迭代法列表反转
    ListNode* reverse(ListNode* node)
    {
        ListNode *prev=NULL;
        ListNode *nxt;
        while(node!=NULL)
        {
            nxt=node->next;
            node->next=prev;
            prev=node;
            node=nxt;
        }
        return prev;//注意这里返回的是prev,而while里面是node
    }
    bool isPail(ListNode* head) {
        if(head==NULL) return -1;
        if(head->next==NULL) return true;
        //有两个节点
        if(head->next->next==NULL) return head->val==head->next->val?true:false;
        //三个节点 
        ListNode *fast,*slow;//快慢指针:奇数返回中点,偶数返回上中点(少于三个节点的时候都返回的是head节点)
        slow=head;
        fast=head->next;
        while(fast->next!=NULL&&fast->next->next!=NULL)
        {
            slow=slow->next;
            fast=fast->next->next;
        }
        ListNode *pH=head;
        ListNode *pT=reverse(slow->next);//pT是反转以后的节点
        ListNode *pT2=pT;
        slow->next=NULL;//中节点末尾接一个NULL,构造成新的链表
        bool res=true;
        while(pH!=NULL&&pT!=NULL)
        {
            if(pH->val!=pT->val)
            {
                res=false;
                break;
            }
            pH=pH->next;
            pT=pT->next;
            
        }
        
        reverse(pT2);
        
        return res;
    }
};

复制特殊链表

种特殊的单链表节点类描述如下

class Node {

int value;

Node next;

Node rand; 了一条指针)

Node(int val) { value = val; }

}

rand指针是单链表节点结构中新增的指针,rand可能指向链表中的任意一个节点,也可能指向null

给定一个由Node节点类型组成的无环单链表的头节点 head,请实现一个函数完成这个链表的复制,并返回复制的新链表的头节点。

要求

时间复杂度O(N),额外空间复杂度O(1)

利用哈希表把原来的结构全部存起来。

【算法】复制含有随机指针节点的链表 - 云+社区 - 腾讯云 (tencent.com)

进阶解法

思路

1、拷贝节点,例如对于 1->2->3->4 我们插入每个节点的后面插入其copy节点,使之为 1->1'->2->2'->3->3'->4->4' 2、那么我们通过找到源节点,即可找到其copy节点的位置(源节点.next),相当于哈希表的作用 3、最后根据原链表的rand关系,链接copy节点的rand指针 4、最后将链表拆分为原链表和copy链表

先复制节点,达到哈希表的作用,然后利用原链表的rand、next关系进行重新连接,最后一个一个拆分,因为一个隔一个是自己复制的

注意:一定要把rand复制完再进行分裂,不然后面的元素要连在前面的节点上,会找不到的

链表找环?

?基础解法:hash set,先查询每个节点,节点不在set里就加入;第一个查询到已经存在在set里的节点就是第一个入环节点;

快慢指针:使初始的slow、fast指针不在同一位置,有环的链表,slow、fast会相遇(所以一开始的slow、fast不要指在同一位置),然后让fast指针回到远点,slow和fast同时一步一步前进,再次相遇的节点就是入环节点。

单链表只有一个next方向,意味着入环节点只有一个,不会进了再出各种复杂的结构

链表相交

节点相交,相交的节点与节点的值无关,只与节点的内存大小有关。

基础解法:哈希表:把一个链表全放入hash set,然后遍历另一个链表看是否在set中存在,有的话就是第一个相交节点

进阶解法:分别遍历链表,找到链表的长度,末尾节点,

链接:https://www.nowcoder.com/questionTerminal/db55f7f21127403cb268ffad9d23af37
来源:牛客网

大体流程分两部分:
第一部分——判断单个链表是否有环
使用两个指针,一个快指针,一个慢指针,快指针一次走两步,慢指针一次走一步;
若快指针最后变为空,则单链表为无环单链表,返回空指针;
若快慢指针在某一时刻指向同一节点,即二者完全一样,则为有环单链表,
此时让快指针重新指向链表头结点,然后快慢指针均一次走一步,
当快慢指针再次相同时,则此节点即为链表入环节点,将其返回。
第二部分——判断链表是否相交
情况一:两链表中一个为有环链表,一个为无环链表,则此时两链表一定不相交,返回空即可;
情况二:两个链表都是无环链表,此时有两种情况,1)两个无环链表相交;2)两个无环链表不相交;
首先遍历两链表,分别得到两个链表的长度,如果两个末尾节点内存地址不同,不可能相交;
取两个长度的差值,然后让长链表先遍历差值长度,此时长链表剩余部分与短链表长度相同,
然后两条链表同时遍历,直到遇到相同节点为止,若相同节点为空,则两链表不相交,返回空,
否则两链表相交,返回相交节点即可;
情况三:两个链表都是有环链表,此时有三种情况,1)两个有环链表不相交;2)两个有环链表相交,且交点在环外;3)两个有环链表相交,且交点在环内。
首先获得两个链表的入环节点,若入环节点相同,则可转变为情况二,此时将入环节点作为链表的终止节点即可;若两个入环节点不同,以一个入环节点开始遍历,若遍历一遍过程中都没有遇见另一个入环节点,则两链表不相交,返回空,若遇到另一入环节点,则说明两链表相交,此时返回任意一个入环节点即可。

代码可参考:?

数据结构与算法 -- 返回两个链表的相交的第一个节点_牛客博客 (nowcoder.net)??

我的leetcode提交?

找单链表的入环节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
 //找到链表第一入环节点,无环返回NULL
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(head==NULL||head->next==NULL) return NULL;

        //fast的节点初始值要在slow节点的初始值
        ListNode *slow=head->next;
        ListNode *fast=head->next->next;
        while(fast!=NULL&&fast->next!=NULL&&slow!=fast)
//因为有环,不会走到空,不用判断.!!!因为要写slow和fast相等的判断条件,所以初始值要让fast比slow快一
        {
            //也可以把fast、fast->next的判空放到这里,如果为空直接返回NULL但其实都是一样的,重复的代码少了些
            slow=slow->next;
            fast=fast->next->next;
        }
        if(fast==NULL||fast->next==NULL) return NULL;//无环
       //有环
        fast=head;
        while(fast!=slow)
        {
            slow=slow->next;
            fast=fast->next;
        }
        return slow;
    }
};

?

?找两个无环链表的公共部分

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if(headA==NULL||headB==NULL) return NULL;
         //遍历两个链表,得到长短链表
        int n=0;
        ListNode *pHA=headA;
        ListNode *pHB=headB;
        while(pHA!=NULL)//如果是有环链表,这里的NULL就应该改成第一个入环节点
        {
            n++;
            pHA=pHA->next;
        }
          while(pHB!=NULL)
        {
            n--;
            pHB=pHB->next;
        }

        pHA=n>0?headA:headB;//pHA指向长链表
        pHB=pHA==headA?headB:headA;
        n=abs(n);
        while(n!=0)
        {
            pHA=pHA->next;//长链表遍历差值长度
            n--;
        }
        while(pHA!=NULL&&pHA!=pHB)
        {
            pHA=pHA->next;
            pHB=pHB->next;
        }
        if(pHA==NULL) return NULL;
         return pHA;
            
        
    }
};

删除链表中的某一个节点

给出了给定的节点,那么把下一个节点的值赋值到给定节点,然后直接让给定节点的next赋值成下下个节点;//借尸还魂

但是本身这个节点没有被删除,且无法删除最后一个节点。

要删除某一个节点,一定要给出头结点。

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

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/10 11:50:50-

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