链表 - 35.复杂链表的复制

在这里插入图片描述
在这里插入图片描述
思路1 :最简单的思路就是直接复制以next为一链的链表,在之后遍历原链表获取random的链表值,在复制链表上去从头到尾的寻找对应的random值。
举例:原链表的节点 A ,在复制链表上节点为 A’ ,A的random指向C,那么 A’ 节点的random也应该指向C‘,但是是A‘链表所在的C’,所以我们需要从头到尾的去寻找C’
这样时间复杂度就为O(n^2)

思路2:我们依旧直接复制原链表的next链,但是我们一边复制一遍存储,因为A节点对一个在复制链表中的节点是A’,所以我们用hashMap去存储,key为A,value为A’。那么我们想一下既然A的random为C,那么A‘对应的random为C’,所以我们就可以通过C直接定位到C‘。HashMap的查询速率几乎等于O(1)。
所以我们需要一个长为原链表长度 n 的的链表,也需要一个大小为 n 的hashMap来存储Key和Value。
所以使用了空间来换时间的思想
时间复杂度:O(n)
空间复杂度:O(n)

public static Node copyRandomList(Node head) {
        if(head == null) return null;
        HashMap<Node,Node> hashMap = new HashMap<>();
        //当random为null时,复制链表中的random也为null
        hashMap.put(null,null);
        Node copytemp = new Node(123);
        //先将原链表按next复制
        Node temp = head;
        Node copyhead = copytemp;
        while(temp != null){
            //边复制,边储存
            copytemp.next = new Node(temp.val);
            hashMap.put(temp,copytemp.next);
            temp = temp.next;
            copytemp = copytemp.next;
        }

        //再遍历原数组匹配random值
        temp = head;
        copytemp = copyhead.next;
        while(temp != null){
            copytemp.random = hashMap.get(temp.random);
            temp = temp.next;
            copytemp = copytemp.next;
        }
        return copyhead.next;

    }


思路三:我们复制的节点直接在原链表上增加复制的节点。
例如 A -》B -》C
复制节点后变成 A -> A’ -> B -> B’ -> C -> C’

那么原链表的A节点random为C节点。那么A的复制节点A’是A的next,那么A’的random也应该为C’,那么C‘的位置就在C节点的后面。所以我们就可以通过A找到C,再通过C找到C’,这样就找到了A‘的random。
所以我们再给节点复制random值时,我们就可以访问原链表节点,
A.next.random = A.random.next;

最后我们把原链表和复制链表分离。偶数为原链表,奇数位新链表。

    public static Node copyRandomList1(Node head) {
        if(head == null) return null;
        Node newHead = null;

        //把复制的节点直接连接到当前节点的后面
//        例如 A -》B -》C
//        复制节点后变成  A -> A' -> B -> B' -> C -> C'

        cloned(head);
        findRandom(head);
        return  getNewHead(head);


        //新链表提取出来
        //a a' b b' c c' null

    }

    //复制
    public static void cloned(Node head){
        Node temp = head;
        while(temp != null){
            Node copyNode = new Node(temp.val);
            copyNode.next = temp.next;
            temp.next = copyNode;
            temp = temp.next.next;
        }
    }
    public static void findRandom(Node head){
        //A.next.random = A.random.next;
        while(head != null ) {
            if(head.random != null){
                head.next.random = head.random.next;
            }
            head = head.next.next;
        }
    }
    public static  Node getNewHead(Node head){
        Node newHead = head.next;
        Node temp = null;
        while(head.next != null ){
            temp = head.next;
            head.next = head.next.next;
            head = temp;
        }
        return newHead;
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 索引的底层实现原理包括: A. B树(B-Tree) B. B+树(B+Tree) C. Hash索引 索引的优化包括: D. 索引分裂 E. 索引合并 F. 索引重建 G. 索引维护(如更新、删除、插入操作) H. 索引优化器(Optimizer)的使用 所以正确答案是: A、B、D、E、F、G、H。 ### 回答2: 索引的底层实现原理是利用数据库中的数据结构,将数据表的某一列或多列按照特定的规则进行排序存储,以便快速查找和访问数据。 优化索引可以从以下几个方面进行: A. B树索引结构优化: B树是索引最常用的数据结构,可以通过调整B树的阶数来优化索引性能。阶数越大,每层节点存储的索引范围就越大,减少了IO操作次数,提高了查询效率。另外,可以使用自适应索引结构,根据查询频率和数据分布情况来自动调整B树的阶数,进一步优化索引性能。 B. B+树叶节点优化: B+树的叶节点存储了数据的真实地址,可以通过增加叶子节点的指针个数来减少IO操作次数,提高查询效率。同时,可以将热点数据放在B+树的叶节点中,以提高查询的命中率,减少磁盘访问次数。 C. B*树分裂策略优化: B*树相对于B树来说有更好的索引性能,可以通过调整分裂策略来进一步优化索引。例如,可以采用快速分裂策略,当某一节点需要分裂时,直接将该节点的部分键移动到新节点,避免了整体数据的复制,提高了分裂的效率。 D. B/树索引压缩优化: B/树是基于B树的变种索引结构,可以通过对索引节点的压缩来减少存储空间的占用。压缩策略可以采用字典压缩、前缀压缩等方法,将相似的键值合并存储,减少了磁盘IO操作,提高了索引的查询性能。 综上所述,索引的底层实现原理是利用特定的数据结构进行快速访问,而优化索引可以通过调整树结构、节点存储方式、分裂策略和压缩方法等手段来提高索引的性能。 ### 回答3: 索引的底层实现原理是通过数据结构来存储和管理数据库中的索引数据。常用的索引实现方式有B+树、哈希表和位图等。 B+树是一种常用的索引结构,其优点是适应范围查询和有序性查询,其在数据库中有广泛的应用。B+树通过在每个非叶子节点存储多个关键字和指针来提高查询效率,同时通过叶子节点的链表来实现有序性查询。B+树的查询、插入和删除操作都能够在O(logN)的时间复杂度内完成,因此被广泛应用于数据库中。 哈希表是另一种常见的索引实现方式,它通过将关键字通过哈希函数映射到哈希表中的位置来加快索引的查找速度。哈希表的查询效率非常高,可以在O(1)的时间复杂度内完成。但是哈希表不支持范围查询和有序性查询,同时对哈希冲突的处理也会增加其操作的复杂性。 位图索引是一种特殊的索引结构,用于处理数据中的布尔类型属性(如性别、职业等),通过对每个属性值使用一个位来表示是否存在,从而实现了高效的布尔操作。位图索引占用的存储空间相对较小,但对于数据的更新操作会有一定的影响。 综上所述,索引的底层实现原理主要有B+树、哈希表和位图等,每种实现方式都有其适用的场景和优化方式。根据具体的应用需求和数据特性,选择合适的索引实现方式以及相应的优化策略可以提高数据库的查询性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值