数据结构与算法复制含有随机指针节点的链表和两个链表相交的一系列问题


目录

  1. 复制含有随机指针节点的链表
  2. 两个链表相交的一系列问题

1. 复制含有随机指针节点的链表

  1. 题目概述

  2. 思路:创建一个HashMap结构,key放当前Node,value放需要复制的Node。

  3. 代码实现


import java.util.HashMap;public class Code_CopyListWithRandom {public static class Node {public int value;public Node next;public Node rand;public Node(int data) {this.value = data;}}public static Node copyListWithRand1(Node head) {HashMap<Node, Node> map = new HashMap<Node, Node>();Node cur = head;while (cur != null) {map.put(cur, new Node(cur.value));cur = cur.next;}cur = head;while (cur != null) {map.get(cur).next = map.get(cur.next);map.get(cur).rand = map.get(cur.rand);cur = cur.next;}return map.get(head);}public static Node copyListWithRand2(Node head) {if (head == null) {return null;}Node cur = head;Node next = null;// copy node and link to every nodewhile (cur != null) {next = cur.next;cur.next = new Node(cur.value);cur.next.next = next;cur = next;}cur = head;Node curCopy = null;// set copy node randwhile (cur != null) {next = cur.next.next;curCopy = cur.next;curCopy.rand = cur.rand != null ? cur.rand.next : null;cur = next;}Node res = head.next;cur = head;// splitwhile (cur != null) {next = cur.next.next;curCopy = cur.next;cur.next = next;curCopy.next = next != null ? next.next : null;cur = next;}return res;}public static void printRandLinkedList(Node head) {Node cur = head;System.out.print("order: ");while (cur != null) {System.out.print(cur.value + " ");cur = cur.next;}System.out.println();cur = head;System.out.print("rand:  ");while (cur != null) {System.out.print(cur.rand == null ? "- " : cur.rand.value + " ");cur = cur.next;}System.out.println();}public static void main(String[] args) {Node head = null;Node res1 = null;Node res2 = null;printRandLinkedList(head);res1 = copyListWithRand1(head);printRandLinkedList(res1);res2 = copyListWithRand2(head);printRandLinkedList(res2);printRandLinkedList(head);System.out.println("=========================");head = new Node(1);head.next = new Node(2);head.next.next = new Node(3);head.next.next.next = new Node(4);head.next.next.next.next = new Node(5);head.next.next.next.next.next = new Node(6);head.rand = head.next.next.next.next.next; // 1 -> 6head.next.rand = head.next.next.next.next.next; // 2 -> 6head.next.next.rand = head.next.next.next.next; // 3 -> 5head.next.next.next.rand = head.next.next; // 4 -> 3head.next.next.next.next.rand = null; // 5 -> nullhead.next.next.next.next.next.rand = head.next.next.next; // 6 -> 4printRandLinkedList(head);res1 = copyListWithRand1(head);printRandLinkedList(res1);res2 = copyListWithRand2(head);printRandLinkedList(res2);printRandLinkedList(head);System.out.println("=========================");}}

2. 两个链表相交的一系列问题

1. 题目描述

2. 思路
  1. 得到入环节点:

    1. 如果节点个数为0,1,2,那么不能形成环,返回null。
    2. 设置两个节点node1,node2,node1为慢节点,一次走一步,node2为快节点,一次走两步
    3. 遍历链表,如果可以相交即为有环
    4. 将node2重新置为head节点,一次走一步,重新从头节点出发,遇到node1即为入环节点
    5. 可以自行测试
  2. 无环链表相交问题

    1. 如果head1或head2一方为null,则不会相交,返回null
    2. 创建cur1和cur2节点,n变量。其中,cur1指向head1节点,cur2指向head2节点,n记录两个链表的长度。
    3. 判断cur1和cur2是否相同,即最后一个节点如果不相同,则不会相交。
    4. 遍历head1,每走一步n++,遍历head2,每走一步n–。最后得到的n值即为两个链表的长度差。
    5. 复用cur1和cur2,当n>0时,说明head1比较长,将cur1指向head1,否则head2比较长,将cur1,指向head2。cur2指向短的链表head1或head2。将n取绝对值。
    6. cur1先走n步,跟cur2一样长时,两者一起走,当两者值一样时即为无环链表相交点。返回cur1即可。
  3. 有环链表相交问题

    1. 创建两个变量cur1,cur2.

    2. 如果两个入环节点相同,则将head1赋给cur1,head2赋给cur2.创建一个变量n记录head1和head2的长度。

    3. 遍历head1,每走一步n++,遍历head2,每走一步n–。最后得到的n值即为两个链表的长度差。

    4. 复用cur1和cur2,当n>0时,说明head1比较长,将cur1指向head1,否则head2比较长,将cur1,指向head2。cur2指向短的链表head1或head2。将n取绝对值。

    5. cur1先走n步,跟cur2一样长时,两者一起走,当两者值一样时即为无环链表相交点。返回cur1即可。

    6. 如果两个入环节点不同,则可能相交也可能不相交。

    7. 使cur1 = loop1.next,遍历环结构,如果途中遇到loop2,即为相交,否则不相交。

3. 代码实现

public class Code_FindFirstIntersectNode {public static class Node {public int value;public Node next;public Node(int data) {this.value = data;}}public static Node getIntersectNode(Node head1, Node head2) {if (head1 == null || head2 == null) {return null;}Node loop1 = getLoopNode(head1);Node loop2 = getLoopNode(head2);if (loop1 == null && loop2 == null) {return noLoop(head1, head2);}if (loop1 != null && loop2 != null) {return bothLoop(head1, loop1, head2, loop2);}return null;}//得到入环节点public static Node getLoopNode(Node head) {if (head == null || head.next == null || head.next.next == null) {return null;}Node n1 = head.next; // n1 -> slowNode n2 = head.next.next; // n2 -> fastwhile (n1 != n2) {if (n2.next == null || n2.next.next == null) {return null;}n2 = n2.next.next;n1 = n1.next;}n2 = head; // n2 -> walk again from headwhile (n1 != n2) {n1 = n1.next;n2 = n2.next;}return n1;}//无环链表相交问题public static Node noLoop(Node head1, Node head2) {if (head1 == null || head2 == null) {return null;}Node cur1 = head1;Node cur2 = head2;int n = 0;while (cur1.next != null) {n++;cur1 = cur1.next;}while (cur2.next != null) {n--;cur2 = cur2.next;}if (cur1 != cur2) {return null;}cur1 = n > 0 ? head1 : head2;cur2 = cur1 == head1 ? head2 : head1;n = Math.abs(n);while (n != 0) {n--;cur1 = cur1.next;}while (cur1 != cur2) {cur1 = cur1.next;cur2 = cur2.next;}return cur1;}//    两个有环链表相交问题public static Node bothLoop(Node head1, Node loop1, Node head2, Node loop2) {Node cur1 = null;Node cur2 = null;if (loop1 == loop2) {cur1 = head1;cur2 = head2;int n = 0;while (cur1 != loop1) {n++;cur1 = cur1.next;}while (cur2 != loop2) {n--;cur2 = cur2.next;}cur1 = n > 0 ? head1 : head2;cur2 = cur1 == head1 ? head2 : head1;n = Math.abs(n);while (n != 0) {n--;cur1 = cur1.next;}while (cur1 != cur2) {cur1 = cur1.next;cur2 = cur2.next;}return cur1;} else {cur1 = loop1.next;while (cur1 != loop1) {if (cur1 == loop2) {return loop1;}cur1 = cur1.next;}return null;}}public static void main(String[] args) {// 1->2->3->4->5->6->7->nullNode head1 = new Node(1);head1.next = new Node(2);head1.next.next = new Node(3);head1.next.next.next = new Node(4);head1.next.next.next.next = new Node(5);head1.next.next.next.next.next = new Node(6);head1.next.next.next.next.next.next = new Node(7);// 0->9->8->6->7->nullNode head2 = new Node(0);head2.next = new Node(9);head2.next.next = new Node(8);head2.next.next.next = head1.next.next.next.next.next; // 8->6System.out.println(getIntersectNode(head1, head2).value);// 1->2->3->4->5->6->7->4...head1 = new Node(1);head1.next = new Node(2);head1.next.next = new Node(3);head1.next.next.next = new Node(4);head1.next.next.next.next = new Node(5);head1.next.next.next.next.next = new Node(6);head1.next.next.next.next.next.next = new Node(7);head1.next.next.next.next.next.next = head1.next.next.next; // 7->4// 0->9->8->2...head2 = new Node(0);head2.next = new Node(9);head2.next.next = new Node(8);head2.next.next.next = head1.next; // 8->2System.out.println(getIntersectNode(head1, head2).value);// 0->9->8->6->4->5->6..head2 = new Node(0);head2.next = new Node(9);head2.next.next = new Node(8);head2.next.next.next = head1.next.next.next.next.next; // 8->6System.out.println(getIntersectNode(head1, head2).value);}}

数据结构与算法之复制含有随机指针节点的链表和两个链表相交的一系列问题相关推荐

  1. 左神算法:复制含有随机指针节点的链表 / 复杂链表的复制(Java版本)

    本题来自左神<程序员代码面试指南>"复制含有随机指针节点的链表"题目. 题目 一种特殊的链表节点类描述如下: public static class Node {pub ...

  2. 链表问题9——复制含有随机指针节点的链表(进阶)

    题目 具体题目信息可以参考上一篇文章. 进阶:不使用额外的数据结构,只用有限几个变量,且在时间复杂度为O(N)内完成原问题要实现的函数. 思路 进阶解法不使用哈希表来保存对应关系,而只采用有限的几个变 ...

  3. 链表问题9——复制含有随机指针节点的链表(初阶)

    题目 public class Node{public int value;public Node next;public Node rand;public Node(int data){this.v ...

  4. 复制含有随机指针节点的链表~哈希表的使用~(⌒▽⌒)

    题目意思就是说给你给head 的Node节点(这是一个比较特殊的链表),来拷贝出它地结构出来. 方法一:借助HashMap的特性,定义一个HashMap<Node,Node> map对象, ...

  5. 算法练习day10——190328(根据指定值划分单链表、复制含有rand指针节点的链表、两个单链表相交)

    1.将单向链表按某值划分成左边小. 中间相等. 右边大的形式 [题目] 给定一个单向链表的头节点head, 节点的值类型是整型, 再给定一个整数pivot. 实现一个调整链表的函数, 将链表调整为左部 ...

  6. 如何复制一个含有随机指针节点的链表

    复制含有随机指针节点的链表 一种特殊的链表节点类描述如下: public class Node {public int value;public Node next;public Node rand; ...

  7. 左神算法基础班3_13深度拷贝含有随机指针的链表

    Problem: 复制含有随机指针节点的链表 [题目] 一种特殊的链表节点类描述如下: public class Node { public int value; public Node next; ...

  8. 数据结构与算法--有序数组中找出和为s的两个数字

    有序数组中找和为s的两个数字 题目:输入一个递增排序的数组array, 和一个数字s, 在数组中找出两个数,使得这两个数的和是s,如果有多对,输出一对即可. 最简单方案 双循环,每次获取一个数据,和数 ...

  9. 数据结构与算法(python) 线性结构:无序列表 Unordered List以及链表

    参考自 MOOC数据结构与算法Python版 目录 一.什么是列表List 二.抽象数据类型List 2.1 List的基本操作 三. Python实现链表:节点Node 3.1 从尾到头打印链表 一 ...

最新文章

  1. Drug Target Review | 筛选用于抗COVID-19的抗病毒化合物
  2. Double 与 Float 的值的比較结果
  3. 使用pdb调试Python程序
  4. python 调用shell 不阻塞_遇到问题---python调用shell脚本时subprocess.check_call不阻塞
  5. python更改端口
  6. Apache Camel,Spring Boot 实现文件复制,转移 (转)
  7. 车牌识别程序_在线的,离线的车牌识别
  8. Windows7安装VC2015-2019_redist.x64提示“设置失败0xc8000222-未指定的错误”
  9. 迅雷手机版苹果版_「9月22日」最新 苹果IOS手机迅雷Beta版证书修复版 安卓不限速...
  10. 智慧教育平台android,智慧教育平台APP 1.0.2 安卓版
  11. 如何干净的卸载Mac版VMware Fusion
  12. wps计算机里wps云盘图标,我的电脑中的wps网盘图标怎么设置删除
  13. 方差,协方差,标准差和均值标准差等各种差
  14. docker容器内启动mysql服务,报错:New main PID 99 does not belong to service, and PID file is not owned by root.
  15. 弱电机房工程搬迁工作内容(方案)
  16. 全数集结,云上相会 | 大势智慧2022新品发布会改为线上举行
  17. Oracle数据库学习--2个不错的网站
  18. BUUCTF-MRCTF2020
  19. Unity_视频背景
  20. ansible 自动化运维工具——ansible Ad-Hoc 使用

热门文章

  1. 跨主机使用 Rex-Ray volume - 每天5分钟玩转 Docker 容器技术(77)
  2. C++ Tricks
  3. 代理服务器https协议单站点开通注意事项
  4. 自动完成--autoComplete插件(2)
  5. 关于“无法完成该动作 到Microsoft Exchange的连接不可用”的解决办法
  6. 有没有通过代码退出程序的方法--官方解答
  7. Chrome浏览器和百度搜索引擎兼容度不佳
  8. 公司网站Silverlight版^_^
  9. CodeForces - 1332D Walk on Matrix(构造)
  10. SPOJ - PHRASES Relevant Phrases of Annihilation(后缀数组+二分)