文章目录
字节等大厂面试的时候可能会要自己写题目要求的数据结构。
// 自己定义链表节点
class Node{
int val;
Node next;
Node random;
public Node(int val){
this.val = val;
// 进行初始化!
this.next = null;
this.random = null;
}
}
1.带随机指针的链表深拷贝
链表深拷贝,纯本人菜鸡手写。面试官可能并 不希望 你使用哈希表。
1.1.哈希表
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
class Solution {
public Node copyRandomList(Node head) {
if(head==null) return null;
// 第一次复制 整个链表
Map<Node,Node> map = new HashMap<>();
Node res = new Node(head.val);
Node temp = head;
Node temp1 = res;
// 复制单独的链表
map.put(temp,temp1);
while(temp.next!=null){
temp = temp.next;
Node nextn = new Node(temp.val);
temp1.next =nextn;
temp1 = temp1.next;
// 链表保存 节点
// list.add(temp1);
map.put(temp,temp1);
}
// 复制random
temp = head;
temp1 = res;
if(temp.random==null){
temp1.random =null;
}else{
temp1.random = map.get(temp.random);
}
while(temp1.next!=null){
temp = temp.next;
temp1 = temp1.next;
if(temp.random==null){
temp1.random =null;
}else{
temp1.random = map.get(temp.random);
}
}
return res;
}
}
参考其他大佬的哈希表写法
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
class Solution {
public Node copyRandomList(Node head) {
//边界条件
if(head==null) return null;
//实现遍历链表
Node node = head;
Map<Node,Node> map = new HashMap<>();
//把源链表和其复制的空链表节点放入哈希表;
//便于对next和random两个指针进行操作;
while(node!=null){
Node temp = new Node(node.val,null,null);
map.put(node,temp);
node = node.next;
}
node = head;
//第二次遍历,将指针进行复制
while(node!=null){
map.get(node).next = map.get(node.next);
//这一步就是深拷贝的关键点,直接拷贝得到的rangdom指针还是指向原链表的!!!
//这一点理解了就OK!
map.get(node).random = map.get(node.random);
node = node.next;
}
return map.get(head);
}
}
1.2 原地修改
这个应该是面试官想要看到的答案。
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
class Solution {
public Node copyRandomList(Node head) {
if(head==null) return null;
Node cur = head;
// 在初始列表上复制
while(cur != null) {
Node temp = new Node(cur.val);
// 把复制后的节点插入到当前节点的后面
temp.next = cur.next;
cur.next = temp;
cur = temp.next;
}
cur = head;
// 操作random
while(cur!=null){
if(cur.random!=null){
// 指向random的下一个,就是复制后的random
cur.next.random = cur.random.next;
}
cur = cur.next.next;
}
// 3. 拆分
cur= head;//拆原链表的工具
Node res = head.next;
Node temp = head.next;//拆新链表的工具
while(temp.next!=null){
// 这个顺序错了会报错,一定先操作前面的,按照先后顺序。
cur.next = cur.next.next;
temp.next = temp.next.next;
cur = cur.next;
temp = temp.next;
}
cur.next =null;
return res;
}
}