剑指Offer面试题26复杂链表的复制,面试题27二叉搜索树和双向链表(递归)
来源:互联网 发布:小林一茶 知乎 编辑:程序博客网 时间:2024/05/29 12:26
面试题26:复杂链表的复制
复制一个复杂链表,这个链表除了next指针,还有指向任意一个结点的sibling指针或空指针。
思路1:一个效率很低的方法:分两步,先复制一遍next链表,然后设置sibling指针。但由于不知道它指向的位置,所以要遍历一遍链表(在原链表中,从头走了几步,在新链表中,也走几步,这就能确定位置了),这样每个结点设置sibling都要经过O(n)步,总复杂度O(n^2)。
思路2:用空间换时间:和上边一样还是两步,区别在于第一步的时候要记录sibling的配对信息到一个哈希表中,这样第二步就能在O(1)时间内完成单个节点的sibling的设置。用O(n)的空间复杂度换来了O(n)的时间复杂度。
思路3:不用辅助空间实现O(n)的效率:三步,1,创建结点n的复制n',n指向n',n'指向下一个原始结点。2,设置sibling,原始结点指向谁,复制的结点就指向对应的复制。3,把这个长链表拆分成两个链表,完成复制。
本题Java实现如下:
public class ComplexList {//调用ComplexListNode clone(ComplexListNode head){cloneNodes(head);connectSiblingNodes(head);return reconnectNodes(head);}//第一步,复制结点void cloneNodes(ComplexListNode head){ComplexListNode p = head;while(p != null){ComplexListNode cloned = new ComplexListNode(p.value);cloned.next = p.next;p.next = cloned;p = cloned.next;}}//第二步,设置siblingvoid connectSiblingNodes(ComplexListNode head){ComplexListNode p = head;while(p != null){if(p.sibling != null){p.next.sibling = p.sibling.next;}p = p.next.next;}}//第三步,拆分ComplexListNode reconnectNodes(ComplexListNode head){ComplexListNode p = head;ComplexListNode clonedHead = null;ComplexListNode tempHead = null;if(p != null){clonedHead = p.next;tempHead = clonedHead;p.next = clonedHead.next;p = p.next;}while(p != null){tempHead.next = p.next;tempHead = tempHead.next;p.next = tempHead.next;p = p.next;}return clonedHead;}//打印void print(ComplexListNode head){if(head == null ) return;while(head != null){System.out.println(head.value);if(head.sibling != null){System.out.println(head.sibling);}head = head.next;}}public static void main(String[] args) {ComplexList test = new ComplexList();ComplexListNode root=new ComplexListNode(0);ComplexListNode node1=new ComplexListNode(1);ComplexListNode node2=new ComplexListNode(2);ComplexListNode node3=new ComplexListNode(3);ComplexListNode node4=new ComplexListNode(4);root.next = node1;root.sibling = node2;node1.next = node2;node1.sibling = node4;node2.next = node3;node3.next = node4;test.print(root);test.print(test.clone(root));}}class ComplexListNode{int value;ComplexListNode next,sibling;ComplexListNode(int x){value = x;}}
面试题27:二叉搜索树与双向链表(递归)
将二叉搜索树转换成一个排序的双向链表,要求不能创建新的结点,只能改变树中结点的指向。
思路:搜索树的中序遍历结果是排好序的,如果把它变成排序的双向链表,根结点一定和左子树里最大的结点相连,也一定和右子树最小的结点相连。然后对于左右子树的根结点,递归处理。
本题Java实现如下:
public class Convert {private BiTree convert(BiTree root){//这里返回二叉树表示的双向链表BiTree lastNode = null;//指向双向链表尾端(值最大的结点)BiTree headNode = convertNode(root,lastNode);//后边函数返回的是双向链表尾结点,我们需要头结点while(headNode != null && headNode.left != null){headNode = headNode.left;}return headNode;}private BiTree convertNode(BiTree root,BiTree lastNode){if(root == null){return null;}BiTree current = root;//按照中序遍历左根右的顺序来,左if(current.left != null){lastNode = convertNode(current.left, lastNode);}//根,此时lastNode应是左子树的最大值,与根相连后,根变成了新的lastNodecurrent.left = lastNode;if(lastNode != null){lastNode.right = current;}lastNode = current;//右if(current.right != null){lastNode = convertNode(current.right, lastNode);}return lastNode;}public static void main(String[] args) {Convert test = new Convert();BiTree A1 = new BiTree(4);BiTree A2 = new BiTree(2);BiTree A3 = new BiTree(5);BiTree A4 = new BiTree(1);BiTree A5 = new BiTree(3);A1.left = A2;A1.right = A3;A2.left = A4;A2.right = A5;BiTree a = test.convert(A1);while(a != null){System.out.println(a.value);a = a.right;}}}class BiTree{int value;BiTree left,right;BiTree(int x){value = x;}}
0 0
- 剑指Offer面试题26复杂链表的复制,面试题27二叉搜索树和双向链表(递归)
- 剑指offer面试题27:二叉搜索树和双向链表
- 【剑指offer】4.4分解让复杂问题简单化——面试题27:二叉搜索树与双向链表
- 【面试题】剑指Offer-27-将二叉搜索树转换成排序的双向链表
- [剑指offer][面试题26]复杂链表的复制
- 剑指offer 面试题26复杂链表的复制
- 【剑指offer】面试题26:复杂链表的复制
- 剑指Offer:面试题26 复杂链表的复制
- 《剑指Offer》面试题26:复杂链表的复制
- 剑指offer面试题26-复杂链表的复制
- 剑指offer-面试题26:复杂链表的复制
- 剑指Offer----面试题26:复杂链表的复制
- 剑指offer 面试题26 复杂链表的复制
- 剑指offer面试题26:复杂链表的复制
- 剑指offer--面试题26:复杂链表的复制
- 剑指Offer---面试题26:复杂链表的复制
- 剑指offer-面试题26-复杂链表的复制
- 剑指offer-面试题26 复杂链表的复制
- Mysql 日期,时间函数
- Struts2内置拦截器timer的使用
- 二分搜索树常见操作(C++版)
- openssl RSA DSA 加密算法使用
- 截取手机号,截取名字
- 剑指Offer面试题26复杂链表的复制,面试题27二叉搜索树和双向链表(递归)
- AVR单片机软件按钮消抖与确认
- mysql中各种类型变量的定义以及赋值使用
- Android中WebView使用
- 【程序48】 题目:某个公司采用公用电话传递数据,数据是四位的整数, 在传递过程中是加密的,加密规则如下:每位数字都加上5, 然后用和除以10的余数代替该数字,再将第一位和第四位交换, 第二位
- LeetCode :【Easy】344. Reverse String
- Dockerfile 简版大全,附赠编写实例
- LeetCode : Power of Two
- ps命令详解