• LeetCode 哈希表 138. 复制带随机指针的链表(链表,哈希表存位置)


     

     说到底就是要把给出的链表完整拷贝一份

    如果仅仅需要拷贝正常的链表的话,只需要在循环中不断创建val和原始链表相同的节点并且将其连起来就行了。

    加了这个random这个节点则较为复杂些。问题在于,random指向后是不连续的,这样在新的链表中没法遍历,说到底就是找不到指向的位置

    很直觉的想到给节点编上号,这样就能通过节点找位置,通过位置找节点了

    一开始的想法是建立两个Hashmap,

    一个是<Node,Integer>,用于放原链表

    一个是<Integer,Node>,用于放新的链表

    这样是因为原链表需要通过节点找序号,新链表需要通过序号找节点

    代码就写成了这样:

    class Solution {
    
        public static Node copyRandomList(Node head) {
            HashMap<Node,Integer> hashMap1=new HashMap<Node,Integer>();
            HashMap<Integer,Node> hashMap2=new HashMap<Integer,Node>();
            int count=0;
            while(head!=null)
            {
                hashMap1.put(head,count);
                hashMap2.put(count,new Node(head.val));
                if(count!=0)
                {
                    hashMap2.get(count-1).next=hashMap2.get(count);
                }
    
                head=head.next;
                count++;
            }
            hashMap1.put(null,count+1);
            hashMap2.put(count+1,null);
            head=hashMap1.keySet().iterator().next();
            count=0;
            while(head!=null)
            {
                Node no=hashMap2.get(hashMap1.get(head.random));
                hashMap2.get(count).random=no;
                count=count+1;
                head=head.next;
            }
            System.out.println(hashMap2.containsValue(hashMap2.get(2).random));
            return hashMap2.get(0);
    
    
        }

     LeetCode中出现了奇怪的bug,判定所有的新节点中的random都是null,但我调试了不是这样的,所以我觉得应该是bug吧。

    但看了一个解法恍然大悟,搞什么节点-序号,序号-节点。直接节点对节点存在hashmap中就好了嘛。重要的是找位置

    class Solution {
        public Node copyRandomList(Node head) {
            if(head==null) {
                return null;
            }
            //创建一个哈希表,key是原节点,value是新节点
            Map<Node,Node> map = new HashMap<Node,Node>();
            Node p = head;
            //将原节点和新节点放入哈希表中
            while(p!=null) {
                Node newNode = new Node(p.val);
                map.put(p,newNode);
                p = p.next;
            }
            p = head;
            //遍历原链表,设置新节点的next和random
            while(p!=null) {
                Node newNode = map.get(p);
                //p是原节点,map.get(p)是对应的新节点,p.next是原节点的下一个
                //map.get(p.next)是原节点下一个对应的新节点
                if(p.next!=null) {
                    newNode.next = map.get(p.next);
                }
                //p.random是原节点随机指向
                //map.get(p.random)是原节点随机指向  对应的新节点 
                if(p.random!=null) {
                    newNode.random = map.get(p.random);
                }
                p = p.next;
            }
            //返回头结点,即原节点对应的value(新节点)
            return map.get(head);
        }
    }

    最优的解法则又进一步,反正重要的是位置,只要通过旧节点能找到对应的新节点就行,所以直接把新节点插在旧节点后面

    这样不用新建一个HashMap了,空间复杂度变为O1

    class Solution {
        public Node copyRandomList(Node head) {
            if(head==null) {
                return null;
            }
            Node p = head;
            //第一步,在每个原节点后面创建一个新节点
            //1->1'->2->2'->3->3'
            while(p!=null) {
                Node newNode = new Node(p.val);
                newNode.next = p.next;
                p.next = newNode;
                p = newNode.next;
            }
            p = head;
            //第二步,设置新节点的随机节点
            while(p!=null) {
                if(p.random!=null) {
                    p.next.random = p.random.next;
                }
                p = p.next.next;
            }
            Node dummy = new Node(-1);
            p = head;
            Node cur = dummy;
            //第三步,将两个链表分离
            while(p!=null) {
                cur.next = p.next;
                cur = cur.next;
                p.next = cur.next;
                p = p.next;
            }
            return dummy.next;
        }
    }    
  • 相关阅读:
    CSRF
    XSS攻击
    SQL 注入
    python解析xml文件
    测试中一些想法
    jenkins+svn完整打包并上传到linux服务器上
    接口自动化测试遭遇问题,excel中取出来的json串,无法使用requests去请求解决办法
    jmeter如何链接数据库并拿到相应值用到请求中
    jmeter如何进行MQTT性能测试(测试前期准备二,MQTT插件及协议了解)
    jmeter如何进行MQTT性能测试(测试前期准备一,性能测试需求)
  • 原文地址:https://www.cnblogs.com/take-it-easy/p/13183885.html
Copyright © 2020-2023  润新知