• Leetcode Copy List with Random Pointer(面试题推荐)


    给大家推荐一道leetcode上的面试题,这道题的详细解说在《剑指offer》的P149页有思路解说。假设你手头有这本书。建议翻阅。

    题目链接 here

    A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

    Return a deep copy of the list.

    RandomList中。每一个节点不光有一个next指针。并且每一个链表节点都有一个random指针。随机指向链表中的一个节点,让你复制这个链表,节点的C++定义例如以下。

    /**
     * Definition for singly-linked list with a random pointer.
     * struct RandomListNode {
     *     int label;
     *     RandomListNode *next, *random;
     *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
     * };
     */

         看到这个题目,预计非常多人的第一反应是,先把这个单链表复制出来,然后挨个找random指向的节点。细致想想这样效率非常低。复制链表非常快。但确定每一个节点的random指针就不easy了,用这样的方法的话。每找一个random指针,都必须遍历一次链表。时间复杂度O(n^2)。

        可能也有人可能会想到时间换空间的方法,用hash把时间复杂度降到O(n)。

        当然,还有更省时省空间的方法。

         大概思路就是,在原链表的基础上,把每一个节点复制一份加的原来节点的后面,然后设置好新节点random指针,在把全部的新节点从原链表中分离出来。构成一个新链表,这个链表就是我们要的原链表的拷贝。

        以下有三个函数,第一个明显就是复制新节点并把其增加到被复制节点的后面。第二个。由于新节点的random指针还是指向旧节点的。要把它指向新节点。非常easy,由于每一个节点的新节点都是在原来的节点之后的。

    第三个函数。把新节点从原链表中抽离,构成一个新链表。

       这样的方法的优点就是。时间复杂度仅仅有O(n),并且我们不须要额外的空间。

    class Solution {
    public:
        void CloneNode(RandomListNode *head) {
            RandomListNode * p = head;
            while (NULL != p) {
                RandomListNode * CloneNode = new RandomListNode(p->label);
                CloneNode->next = p->next;
                CloneNode->random = p->random;
                p->next = CloneNode;
                p = CloneNode->next;
            }
        }
        
        void ConnectRandomNode(RandomListNode * head) {
            RandomListNode * p = head;
            while (NULL != p) {
                RandomListNode *pclone = p->next;
                if (NULL != pclone->random) {
                    pclone->random = pclone->random->next;
                }
                p = pclone->next;
            }
        }
        RandomListNode *copyRandomList(RandomListNode *head) {
            if (NULL == head)
                return head;
            CloneNode(head);
            ConnectRandomNode(head);
            RandomListNode *pnode = head;
            RandomListNode *pclonehead = pnode->next;
            RandomListNode *pclonenode = pnode->next;
            while (NULL != pnode) {
                pnode->next = pclonenode->next;
                pnode = pnode->next;
                if (NULL != pnode){
                     pclonenode->next = pnode->next;
                     pclonenode = pclonenode->next;
                }
            }
            return pclonehead;
        }
        
    };


  • 相关阅读:
    vagrant up报错 Warning: Authentication failure. Retrying...解决方案
    node读写Excel操作
    批量转换word为pdf
    分享7个shell脚本实例--shell脚本练习必备
    shell脚本实例,通向shell脚本大师的必经之路
    前端优化DNS预解析
    如何选择开源协议
    深入理解document.referrer的用法
    使用 WebRTC 构建简单的前端视频通讯
    深入理解WebRTC
  • 原文地址:https://www.cnblogs.com/lytwajue/p/7299495.html
Copyright © 2020-2023  润新知