JZ25复杂链表的复制

>>点击此链接

JZ36两个链表的第一个公共结点

题目描述
输入两个无环的单链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)

分析:
方法1:暴力破解,使用两个循环

方法2:
           看下面的链表例子:
0-1-2-3-4-5-null
a-b-4-5-null
代码的ifelse语句,对于某个指针p1来说,其实就是让它跑了连接好的的链表,长度就变成一样了。
如果有公共结点,那么指针一起走到末尾的部分,也就一定会重叠。看看下面指针的路径吧。
p1: 0-1-2-3-4-5-null(此时遇到ifelse)-a-b-4-5-null
p2: a-b-4-5-null(此时遇到ifelse)0-1-2-3-4-5-null
因此,两个指针所要遍历的链表就长度一样了!
如果两个链表存在公共结点,那么p1就是该结点,如果不存在那么p1将会是null。

方法3:还是个重复问题,使用set 可

方法4: 双指针法
先统计两个链表的长度。让较长的先走,直到两个链表长度一样,这个时候两个链表再同时每次往后移一步, 看节点是否一样.

代码

 /***  暴力破解:双重循环*/public static  ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {if(pHead1 == null || pHead2==null){return null;}ListNode cur2 = pHead2;while (pHead1!=null){while (pHead2!=null){if(pHead1 == pHead2){return pHead1;}pHead2 = pHead2.next;}pHead1 = pHead1.next;pHead2 = cur2;}return null;}/*** p1: 0-1-2-3-4-5-null(此时遇到ifelse)-a-b-4-5-null* p2: a-b-4-5-null(此时遇到ifelse)0-1-2-3-4-5-null* 因此,两个指针所要遍历的链表就长度一样了!* 如果两个链表存在公共结点,那么p1就是该结点,如果不存在那么p1将会是null。*/public static  ListNode FindFirstCommonNode2(ListNode pHead1, ListNode pHead2) {if(pHead1 == null || pHead2==null){return null;}ListNode p1 = pHead1;ListNode p2 = pHead2;while (p1 != p2){p1 = p1.next;p2 = p2.next;if(p1 != p2){//因为上面两行已经改变了p1 , p2所以还要先判断一下if(p1 == null){p1 = pHead2;}if(p2 == null){p2 = pHead1;}}}return p1;}/*** 约等于 重复节点,使用set*/public static  ListNode FindFirstCommonNode3(ListNode pHead1, ListNode pHead2) {HashSet<ListNode> set = new HashSet<>();while (pHead1!=null){set.add(pHead1);pHead1 = pHead1.next;}while (pHead2!=null){if(set.contains(pHead2)){return pHead2;}pHead2 = pHead2.next;}return null;}/*** 双指针法* 先统计两个链表的长度。让较长的先走,直到两个链表长度一样,这个时候两个链表再同时每次往后移一步,* 看节点是否一样,*/public  ListNode FindFirstCommonNode4(ListNode pHead1, ListNode pHead2) {int lenA = length(pHead1);int lenB = length(pHead2);//如果两个的长度不一样,那么使长度一样while (lenA != lenB){if(lenA > lenB){pHead1 = pHead1.next;lenA--;}else {pHead2 = pHead2.next;lenB--;}}//走到这里,说明长度一样了while (pHead1!=pHead2){pHead1 = pHead1.next;pHead2 = pHead2.next;}return pHead1;}public static int length(ListNode node){int len = 0;while (node != null){len++;node = node.next;}return len;}

JZ55链表中环的入口结点

题目描述
   给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

分析:

方法1:算是重复问题。使用HashSet

方法2:双指针法
参考牛客网@却顾所来径

思路:
    设置快慢指针,都从链表头出发,快指针每次走两步,慢指针一次走一步,假如有环,一定相遇于环中某点(结论1)。接着让两个指针分别从相遇点和链表头出发,两者都改为每次走一步,最终相遇于环入口(结论2)。以下是两个结论证明:
两个结论:
1、设置快慢指针,假如有环,他们最后一定相遇。
2、两个指针分别从链表头和相遇点继续出发,每次走一步,最后一定相遇与环入口。

证明结论1: 设置快慢指针fast和low,fast每次走两步,low每次走一步。假如有环,两者一定会相遇(因为low一旦进环,可看作fast在后面追赶low的过程,每次两者都接近一步,最后一定能追上)。

证明结论2:
设:
链表头到环入口长度为–a
环入口到相遇点长度为–b
相遇点到环入口长度为–c
相遇时:
快指针路程=a+(b+c)k+b ,k>=1
慢指针路程=a+b
快指针走的路程是慢指针的两倍,所以:
(a+b)*2=a+(b+c)k+b
化简可得:
a=(k-1)(b+c)+c 这个式子的意思是: 链表头到环入口的距离=相遇点到环入口的距离+(k-1)圈环长度。其中k>=1,所以k-1>=0圈。所以两个指针分别从链表头和相遇点出发,最后一定相遇于环入口。

代码如下:

 /***  算重复问题,使用HashSet*/public ListNode EntryNodeOfLoop(ListNode pHead) {HashSet<ListNode> set = new HashSet<>();while (pHead != null){if(set.contains(pHead.next)){return pHead.next;}set.add(pHead);pHead = pHead.next;}return null;}/*** 双指针法,妙啊!*/public ListNode EntryNodeOfLoop2(ListNode pHead) {ListNode fast = pHead;ListNode slow = pHead;while (fast != null && fast.next!=null){//只用判断fast是否为nullfast = fast.next.next;slow = slow.next;if(fast == slow){break;}}if(fast==null ||fast.next == null){return null;}//走到这块说明两个指针相遇//然后将slow指向pHeadslow = pHead;while (fast != slow){fast = fast.next;slow = slow.next;}return fast;}

JZ56删除链表中重复的结点

题目描述
    在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

示例1
输入:
{1,2,3,3,4,4,5}

返回值:
{1,2,5}

分析:

方法1: 使用Set(看到关于重复的就。。)
       多次遍历,第一次遍历把重复的结点值存入 set 容器,第二次遍历,当结点值存储在 set 容器中,就删除该结点。

方法2:遍历的同时删除:
       设置两个结点 pre 和 cur, 当 cur 和 cur.next 值相等,cur 一直向前走,直到不等退出循环, 这时候 cur 指的值还是重复值,调整 cur 和 pre 的指针再次判断

代码:

 /*** 一看到重复,就set* 多次遍历,第一次遍历把重复的结点值存入 set 容器,* 第二次遍历,当结点值存储在 set 容器中,就删除该结点*/public ListNode deleteDuplication(ListNode pHead) {if(pHead == null || pHead.next == null){return pHead;}HashSet<Integer> set = new HashSet<>();ListNode pre = pHead;ListNode cur = pHead.next;//该循环将重复的节点存入set中while (cur != null){if(cur.val == pre.val){set.add(cur.val);}pre = cur;cur = cur.next;}//根据set中的值  删除重复的节点//先判断头节点是否重复while (pHead!=null && set.contains(pHead.val)){pHead = pHead.next;}if(pHead == null){//【记得判空】return null;}//再判断中间的节点pre = pHead;cur = pHead.next;while (cur != null){if(set.contains(cur.val)){pre.next = cur.next;cur = cur.next;}else {pre = cur;cur = cur.next;}}return pHead;}/*** 遍历的同时删除*设置两个结点 pre 和 cur,* 当 cur 和 cur.next 值相等,cur 一直向前走,直到不等退出循环,* 这时候 cur 指的值还是重复值,调整 cur 和 pre 的指针再次判断*/public ListNode deleteDuplication2(ListNode pHead) {if(pHead == null || pHead.next == null){return pHead;}ListNode head = new ListNode(-1);//辅助头节点head.next = pHead;ListNode cur = head.next;ListNode pre = head;while (cur != null){//遇到重复节点if (cur.next != null && cur.next.val == cur.val) {// 相同结点一直前进while (cur.next != null && cur.next.val == cur.val){cur = cur.next;}// 退出循环时,cur 指向重复值,也需要删除,而 cur.next 指向第一个不重复的值// cur 继续前进cur = cur.next;pre.next = cur;}else {//没有遇到pre = cur;cur = cur.next;}}return head.next;}

链表2--JZ25复杂链表的复制JZ36两个链表的第一个公共结点JZ55链表中环的入口结点JZ56删除链表中重复的结点相关推荐

  1. 【Java】牛客网 删除链表中重复的结点

    题目描述 : 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表 1->2->3->3->4->4->5 ...

  2. 剑指offer:删除链表中重复的结点

    题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...

  3. 剑指Offer(Java实现)删除链表中重复的结点

    题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...

  4. 删除链表中重复的结点

    题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针.例如,链表1->2->3->3->4->4->5 处理后为 ...

  5. 剑指offer:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。

    在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后为 1-& ...

  6. 链表题目---4 删除链表中重复的结点 和 判断链表是否为回文链表

    删除链表中重复的结点 /* struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {} ...

  7. 不带头节点的链表有哪些缺点_14. 删除链表中重复的结点

    删除链表中重复的结点 题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4-> ...

  8. 剑指offer之删除链表中重复的结点

    题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...

  9. 剑指offer(C++)-JZ76:删除链表中重复的结点(数据结构-链表)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回 ...

最新文章

  1. MariaDB 基金会 CEO 宣布将于 10 月 1 日卸任
  2. 五大算法设计思想,你都知道吗?
  3. Fedora 下安装Mplayer(添加源和解决错误问题)
  4. RPM vs SRPM
  5. delegate的使用总结
  6. Java File类基本操作
  7. linux切换软件版本,Linux中dpkg工具update-alternatives实现符号链接软件版本的切换(转)...
  8. java安全编码指南之:声明和初始化
  9. nio框架中的多个Selector结构
  10. Long Way To Go 之 Python 5 (2)
  11. c#+wpf项目性能优化之OutOfMemoryException解密
  12. ios给控件添加动画效果
  13. office2016风格后台管理系统html模板下载-uimaker设计
  14. 这个微信隐藏代码,你们现在知道还不晚
  15. SAP-MM-PA精解分析系列之供应商(01)-基本概念及业务介绍
  16. 练习4.圆中四只鸭子在同一个半圆的概率——MATLAB
  17. HEXO+Github博客 更换新域名详解
  18. Mat 的介绍和使用
  19. TPM设备管理,不只是维修保养
  20. 用计算机模拟股票大盘,股票模拟盘操作与实盘不同之处有哪些

热门文章

  1. 从 TWAIN 设备中扫描图像
  2. 瑞萨单片机之data flash的使用(五)
  3. Zebra 打印机模板实现模板标签打印
  4. __cdecl __stdcall
  5. 黄金原野的 “去中心化认证“技术
  6. 【stata】stata软件手动离线安装外部命令logout
  7. 小白系列(1) | 计算机视觉之图像分类
  8. ajax如何隐藏请求参数,全面解析$.Ajax()方法参数(推荐)
  9. 成都大数据语言培训:改变人们的生活的大数据趋势
  10. matlab 向量取倒数,Matlab 求倒数命令及控制方法