2023/3/4[LC:Random_List_Copy]

发布时间 2023-04-18 22:19:52作者: Logic_Han

2023/3/4[LC:Random_List_Copy]

img

1>心得:

  • 写“for"循环之前需要首先思考循环目的结束条件;例如链表的遍历等;
  • 模拟仔细;

2>思路

首先如果是单纯复制一个普通链表:

img需要给前一个copy结点留一个pre指针;以便:pre->next=copy;

3>解法

此题有两个解法

问题的关键在于如何解决指向与当前结点相距不定的”复杂节点“;(如果是正常链表可以留一个pre指针)

解法一:通过HashMap记录对应新旧结点关系

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/
class solution{
    public Node* copy_random_list(Node* head){
        if(!head) return nullptr;
        map<Node*,Node*> map;
        for(Node* p=head;p;p=p->next){
            map.put(p,new Node(p->val));
        }
/*关键for循环*/
        for(Node* q=head;q;q=q->next){
            map.find(q)->second->next=map.get(q->next)->second;
            map.get(q)->second->random=map.get(q->random)->second;
        }
        return map.get(head)->second;
    }
}

解法二:原地重复链表记录新旧关系

img

class Solution {
public:
    Node* copyRandomList(Node* head) {
        if(!head){
            return nullptr;
        }
        for(Node* p=head;p!=nullptr;p=p->next->next){
            Node* new_p=new Node(p->val);
            new_p->next=p->next;
            p->next=new_p;
        }
/*关键for循环*/
        for(Node* p=head;p!=nullptr;p=p->next->next){
            if(p->random){
                p->next->random=p->random->next;//保证是复制的random结点
            }
        }
        Node* ans =head->next;
        Node* q=head;
        Node* r=head->next;
/*q直到null才停,r一次跳两步最后一步会r->null->next报错*/
        for(;r&&r->next&&q;r=r->next,q=q->next){
            q->next=q->next->next;
            r->next=r->next->next;
        }
        q->next=nullptr;
        r->next=nullptr;
        return ans;
    }
};