复杂链表的复制
题目:复制一个复杂链表(每个节点有两个指针,一个指向下一个节点,一个指向任意一个节点)。
思路:先复制主链,暂时不管随机指向的指针,在复制主链的过程中,通过Map建立新旧链中每个节点的对应关系,然后再通过一次遍历,在新链中建立随机指向的指针。
public class Solution {
public RandomListNode Clone(RandomListNode pHead)
{
RandomListNode oldHead = pHead;
Map<RandomListNode, RandomListNode> occurs = new HashMap<>();
RandomListNode newHead = new RandomListNode(0);
RandomListNode cur = newHead;
// 仅复制next,并建立主链节点的映射关系
while(pHead != null){
RandomListNode temp = new RandomListNode(pHead.label);
cur.next = temp;
occurs.put(pHead, temp);
cur = cur.next;
pHead = pHead.next;
}
cur = newHead.next;
pHead = oldHead;
// 根据映射关系,建立random连接
while(pHead != null){
cur.random = (RandomListNode)occurs.get(pHead.random);
cur = cur.next;
pHead = pHead.next;
}
return newHead.next;
}
}
重建二叉树
题目:根据前序遍历序列和中序遍历序列重建二叉树。
思路:不断分割前序遍历和中序遍历序列(分割后的前序、中序序列分别都是子树的对应序列),递归构建。
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if(pre == null || in == null){
return null;
}
return build(pre, in, 0, pre.length-1, 0, in.length-1);
}
public TreeNode build(int[] pre, int[] in, int preStart, int preEnd, int inStart, int inEnd){
if(preStart > preEnd || inStart > inEnd){
return null;
}
TreeNode head = new TreeNode(pre[preStart]);
// 从中序遍历里面找当前根节点的index
int index = 0;
for(int i = inStart; i <= inEnd; i++){
if(pre[preStart] == in[i]){
index = i;
}
}
// 计算左子树的长度
int leftLen = index - inStart;
// 计算右子树的长度
int rightLen = inEnd - index;
if(leftLen > 0){
head.left = build(pre, in, preStart+1, preStart+leftLen, inStart, index-1);
}
if(rightLen > 0){
head.right = build(pre, in, preStart+leftLen+1, preEnd, index+1, inEnd);
}
return head