当前位置: 首页 > news >正文

网上流传的那些关于链表的面试问题

1、在O(1)时间删除链表节点

题目描述:给定链表的头指针和一个节点指针,在O(1)时间删除该节点。

思路分析:用下一个节点的数据覆盖要删除的节点,然后直接删除待删除节点的下一个节点就好了。(狸猫换太子)

如果节点是尾节点时就行不通

void deleteRandomnode(Node *cur){
    //assert(cur != NULL);
    //assert(cur->next != NULL);
    
    Node * cur_Next = cur->next;

    cur->data = cur->next->data;
    cur->next = cur->next->next;
    //delete cur_next; //free(cur_Next)
}    

 

2、单链表的转置

题目描述:输入一个单向链表,输出逆序反转后的链表

思路分析:利用next 和 prev 来将下一个节点指向上个一节点。(实现转置)

Node * reverseByloop(Node *head){
    if(head == NULL || head->next == NULL){
        return head;
    }
    Node * prev, * next;
    prev = next = NULL;

    while(head != NULL){
        next = head->next;
        head->next = prev;
        prev = head;
        head = next;
    }  
   return prev;   }

 

3、求链表倒数第k个节点

问题描述:输入一个单向链表,输出该链表中倒数第k个节点,链表的倒数第0个节点为链表的尾节点(无非就是fast是先走k步还是k-1步)

思路分析:用快慢指针,快指针先走k步然后在和慢指针一起走,快指针走到尾节点,慢指针的位置就刚好是倒数第k个节点。

Node * theKthNode(Node *head, int k){
    if (k < 0) return NULL;
           
    Node * slow, *fast;
    slow = fast = head;
    
    int i = k;
    while(i != 0 && fast != NULL)
        fast = fast->next;
        
     // less then k linked list.
    if(i > 0)
        return NULL;
    
    while(fast != NULL){
        fast = fast->next;
        slow = slow->next;    
    }

    return slow;
}

 

4、求链表的中间节点

问题描述:如果长度为偶数,返回中间两个节点其中一个,为奇数就返回中间节点。

思路分析:这个也用快慢指针,快指针一次跳两个节点,满指针一次一个节点,等快指针指向尾节点的时候,慢指针就在中间节点上。

Node * theIntermediatenode(Node *head){
    
    if(head == NULL){
        return NULL;
    }
    
    Node * slow, *fast;
    slow = fast = head;
    
    while(fast != NULL && fast->next != NULL){
        fast = fast->next->next;
        slow = slow->next;
    }
    
    return slow;
}

如果偶数节点数要返回后面那个中心节点的话,可以if(fast != NULL) return slow->next;

 

5、判断单链表是否存在环

问题描述:输入一个单链表,判断链表是否有环

思路分析:通过快慢指针(快指针两步,慢指针一步),如果存在环,那么他们一定会在环里相遇

_Bool hasCircle(Node *head, Node *meetnode){
    Node *fast, *slow;
    fast = slow = head;

    while(fast != NULL && fast->next != NULL){
        fast = fast->next->next;
        slow = slow->next;
        
        if(fast = slow){
            meetnode = fast;
            return TURE;
        }
    }

    return FALSE;
}

 

6、找到环的入口点

问题描述:输入一个单向链表,判断是否有环,如何找到环的入口点(就是尾节点的next节点)

思路分析:假设环内相遇节点是M,头节点到入口节点距离是a,r入口节点到M距离是b。快慢节点相遇的时候,慢节点走了a+b = n,快节点走了a+b+k圈=2n。

     如果慢节点再从头结点走n到达M,快节点再从M走k圈也将会到达M,那么快慢指针走的路不同的只有a那段,然后他们第一次相遇的节点就是入口节点。

Node * findLoopPort(Node *head){
    //if head empty or single node,the ring does not exist.
    if(head == NULL || head->next == NULL){
        return NULL;
    }

    Node *fast, *slow;
    fast = slow = head;
    if(hasCircle(head, slow)){
        while(fast != slow){
            fast = fast->next;
            slow = fast->next;
        }

        return fast;
    }
          //Non existence ring
   else
        return NULL;
}

 

7、判断两个链表是否相交

问题描述:给出两个单链表的头指针判断链表是否相交

思路分析:两个链表一旦相交,接下来所有节点都是一样的,不论是到空也好还是环也好,判断不带环的节点直接看最后的尾节点是否相等。

_Bool isIntersect(Node *h1, Node *h2){
    if(h1 == NULL || h2 == NULL){
        return FALSE;
    }
    while(h1->next != NULL){
        h1 = h1->next;
    }
    while(h2->next != NULL){
        h2 = h2->next;
    }
    
    if(h1 == h2)
        return TURE;
    else 
        return FALSE;
}

 

8、两个链表相交的第一个公共节点

问题描述:如果两个单链表相交,求出他们的第一个公共节点

思路分析:既然相交节点后面的内容一致,那么算出两个链表的长度并算出差为g然后让长的那个先走g个节点,然后和短链表一起走,知道他们相等就是

     第一个公共节点

int listLength(Node *head){
    int len = 0;
while(head){ len++; head = head->next; } return len; } Node * findFirstIntersectNode(Node *h1, Node *h2){ int len1,len2; len1 = listLength(h1); len2 = listLength(h2); if(len1 > len2){ for(int i = 0; i < len1 - len2; i++) h1 = h1->next; } else{ for(int i = 0; i < len2 - len1; i++) h2 = h2->next; } while(h1 != NULL){ if(h1 == h2) return h1; h1 = h1->next; h2 = h2->next; } return NULL; }

9、链表有环,如何判断相交

问题描述:上面那个是针对无环的,这个是两个有环链表,判断是否相交

问题分析:如果两个带环链表相交那么他们拥有同一个环,环上任意一个节点都存在于两个链表上,因此可以判断一链表上相遇的那个节点在不在另外一个链表上。

_Bool isIntersectWithLoop(Node *h1, Node *h2){
    Node *circlenode1, *circlenode2;
    if(!hasCircle(h1, circlenode1))
        return FALSE;
    if(!hasCircle(h2, circlenode2))
        return FALSE;

    Node *temp = circlenode2->next;
    while(temp != circlenode2){
        if(temp == circlenode1)
            return TURE;
        temp = temp->next;
    }

    return FALSE;
}

未完待续....

转载于:https://www.cnblogs.com/BMing/p/10028069.html

相关文章:

  • JavaScript的使用你知道几种?(上)
  • 根据开始日期和当前日期,获取当前是第几周
  • 服务发现全量配置整理(更新中)
  • MySql版本查看
  • 业务员类别窗体的制作
  • lucene 思维导图,让搜索引擎不再难懂
  • “如何让团队成员获得成长?”四名高段位 CTO 为你解惑
  • 二叉树应用
  • Yii2 RULE 校验器
  • 使用xorm工具,根据数据库自动生成 go 代码
  • 服务端渲染(SSR)
  • 2019互联网校招薪资表: BAT、华为还没有TMD高
  • 使用java执行ffmpeg命令进行推流操作
  • vim利用vundle安装YouCompleteMe
  • 高性能负载均衡之分类架构
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • Angular Elements 及其运作原理
  • CSS 提示工具(Tooltip)
  • Docker: 容器互访的三种方式
  • EOS是什么
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • input的行数自动增减
  • js算法-归并排序(merge_sort)
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • PHP CLI应用的调试原理
  • SpiderData 2019年2月23日 DApp数据排行榜
  • webgl (原生)基础入门指南【一】
  • 阿里云Kubernetes容器服务上体验Knative
  • 笨办法学C 练习34:动态数组
  • 浮现式设计
  • 高性能JavaScript阅读简记(三)
  • 简单易用的leetcode开发测试工具(npm)
  • 近期前端发展计划
  • 前端js -- this指向总结。
  • 我与Jetbrains的这些年
  • Java性能优化之JVM GC(垃圾回收机制)
  • 从如何停掉 Promise 链说起
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • # Apache SeaTunnel 究竟是什么?
  • #define
  • $jQuery 重写Alert样式方法
  • (007)XHTML文档之标题——h1~h6
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (a /b)*c的值
  • (ctrl.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“
  • (javascript)再说document.body.scrollTop的使用问题
  • (Java数据结构)ArrayList
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (二)斐波那契Fabonacci函数
  • (附源码)springboot教学评价 毕业设计 641310
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • (转)使用VMware vSphere标准交换机设置网络连接