链表问题----复杂链表的复制+二叉搜索树与双向链表(Java)


复杂链表的复制

题目描述:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点)。

(1)利用hash表记录随机指针对应关系;
import java.util.HashMap;
/*
public class RandomListNode {
     int label;
     RandomListNode next = null;
     RandomListNode random = null;
 
     RandomListNode(int label) {
         this.label = label;
     }
}
*/
public class Solution {
     public RandomListNode Clone(RandomListNode pHead)
 
         {
            if (pHead== null ){
                 return pHead;
             }
             RandomListNode head=pHead;
             RandomListNode result= new RandomListNode(pHead.label);
             RandomListNode temp=result;
             HashMap<RandomListNode,RandomListNode> map= new HashMap<RandomListNode,RandomListNode>();
             map.put(pHead, temp);
             pHead=pHead.next;
             while (pHead!= null ){
                 temp.next= new RandomListNode(pHead.label);
                 map.put(pHead, temp.next);
                 temp=temp.next;
                 pHead=pHead.next;
             }
             pHead=head;
             temp=result;
             while (pHead!= null ){
                 if (pHead.random!= null ){
                     temp.random=map.get(pHead.random);
                 }
                 pHead=pHead.next;
                 temp=temp.next;
             }
             return result;
         }
     
}
(2)将每个结点复制并链接到原链表中间,再拆分。
/*
public class RandomListNode {
     int label;
     RandomListNode next = null;
     RandomListNode random = null;
 
     RandomListNode(int label) {
         this.label = label;
     }
}
*/
public class Solution {
     public RandomListNode Clone(RandomListNode pHead)
     {
         if (pHead== null ){
             return pHead;
         }
         RandomListNode head=pHead;
         RandomListNode result;
         while (pHead!= null ){
             RandomListNode temp= new RandomListNode(pHead.label);
             temp.next=pHead.next;
             pHead.next=temp;
             pHead=temp.next;
         }
         pHead=head;
         while (pHead!= null ){
             if (pHead.random!= null ){
                 pHead.next.random=pHead.random.next;
             }
             pHead=pHead.next.next;
         }
         result=pHead=head.next;
         while (pHead.next!= null ){
             head.next=pHead.next;
             head=head.next;
             pHead.next=head.next;
             pHead=pHead.next;
         }
         head.next= null ;
         return result;
     }
}

二叉搜索树与双向链表

题目描述:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。


(1)利用栈
import java.util.Stack;
/**
public class TreeNode {
     int val = 0;
     TreeNode left = null;
     TreeNode right = null;
 
     public TreeNode(int val) {
         this.val = val;
 
     }
 
}
*/
public class Solution {
     public TreeNode Convert(TreeNode pRootOfTree) {
         if (pRootOfTree== null ||pRootOfTree.left== null &&pRootOfTree.right== null ){
             return pRootOfTree;
         }
         Stack<TreeNode> stack= new Stack<TreeNode>();
         TreeNode p=pRootOfTree;
         TreeNode pre= null ;
         TreeNode result= null ;
         while (p!= null ||!stack.empty()){
             while (p!= null ){
                 stack.push(p);
                 p=p.left;
             }
             p=stack.pop();
             if (pre!= null ){
                 if (pre.left== null ){
                     result=pre;
                 }
                 pre.right=p;
                 p.left=pre;
             }
             pre=p;
             p=p.right;
         }
         return result;
     }
}

(2)利用递归
/**
public class TreeNode {
     int val = 0;
     TreeNode left = null;
     TreeNode right = null;
 
     public TreeNode(int val) {
         this.val = val;
 
     }
 
}
*/
public class Solution {
     public TreeNode Convert(TreeNode pRootOfTree) {
         if (pRootOfTree== null ||pRootOfTree.left== null &&pRootOfTree.right== null ){
             return pRootOfTree;
         }
         if (pRootOfTree.left!= null ){
             TreeNode temp=Convert(pRootOfTree.left);
             while (temp.right!= null ){
                 temp=temp.right;
             }
             pRootOfTree.left=temp;
             temp.right=pRootOfTree;
         }
         if (pRootOfTree.right!= null ){
             TreeNode temp=Convert(pRootOfTree.right);
             pRootOfTree.right=temp;
             temp.left=pRootOfTree;
         }
         while (pRootOfTree.left!= null ){
             pRootOfTree=pRootOfTree.left;
         }
         return pRootOfTree;
     }
}
(3)使用二叉树的神级遍历发,时间复杂度O(n),额外空间复杂度O(1)
/**
public class TreeNode {
     int val = 0;
     TreeNode left = null;
     TreeNode right = null;
 
     public TreeNode(int val) {
         this.val = val;
 
     }
 
}
*/
public class Solution {
     public TreeNode Convert(TreeNode pRootOfTree) {
         if (pRootOfTree== null ||pRootOfTree.left== null &&pRootOfTree.right== null ){
             return pRootOfTree;
         }
         TreeNode cur1=pRootOfTree;
         TreeNode cur2,pre= null ;
         TreeNode result= null ;
         while (cur1!= null ){
             cur2=cur1.left;
             if (cur2== null ||cur2.right==cur1){
                 if (result== null ){
                     result=cur1;
                 }
                 else {
                     pre.right=cur1;
                 }
                 cur1.left=pre;
                 pre=cur1;
                 cur1=cur1.right;
             }
             else {
                 while (cur2.right!= null ){
                     cur2=cur2.right;
                 }
                 cur2.right=cur1;
                 cur1=cur1.left;
                 cur2.right.left=cur2;
             }
         }
         return result;
     }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值