好题分享(2023.11.5——2023.11.11)

news2024/11/18 15:41:02

目录

前情回顾:

前言:

题目一:补充《移除链表元素》

题目二:《反转链表》

解法一:三指针法

解法二:头插法 

题目三: 《相交链表》

题目四:《合并两个有序数列》

题目五:《链表中倒数第K个节点》

题目六:《链表的分割》

题目七:《链表的回文结构》 

题目八:《环形链表(一)》 

 题目九:《环形链表(二)》 

由题目八引出结论:

对于第九题的算法:

总结:

题目十:《随机链表的复制》

1.先拷贝各个节点,再连接起来

2.对random进行赋值

3.断开连接

总结:


前情回顾:

我们在上一篇好题分析中,分析了以下几题:

《合并两个有序数组》《移除链表元素》《链表的中间节点》

上一篇的好题分析的blog在

好题分析(2023.10.29——2023.11.04)-CSDN博客

前言:

本次好题分享,我们将对《移除链表元素》进行一种算法即思路进行补充,因为在之后的题目,都是围绕此算法来实现的

同时,我们还将对Leecode和牛客网上的众多题目进行分析:

《反转链表》《相交链表》《环形链表(一)》《环形链表(二)》《随机链表的复制》《合并两个有序链表》

《链表中倒数第K个节点》《链表分割》《链表的回文结构》

题目一:补充《移除链表元素》

 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

​ 

我们在上一篇blog中,我们是利用三个指针来进行操作,在删除节点前,保存该节点前后的节点,再进行修改指向的操作,此算法的不足之处,就在于如果我们要删除的元素位于头结点,那么这个时候就要考虑另外一种情况了。

接下来的算法将可以省去上述步骤,且在之后的刷题中会更高效!

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 
 //创建“新链表”
struct ListNode* removeElements(struct ListNode* head, int val) {
    struct ListNode* newhead = NULL,*cur = head,*tail = NULL;
    while(cur)
    {
        //不是val节点的拿下来尾插
        if(cur->val != val)
        {
            //尾插
            if(tail==NULL)
            {
                newhead = tail =cur;
            }
            else
            {
                tail->next = cur;
                tail = tail->next;
            }
            cur = cur->next;
        }
        else
        {
            cur =cur->next;
        }
    }
    if(tail)
    {
        tail->next = NULL;
    }
    return newhead;
}

 该算法是先创建一个新链表,将需要的节点连接到新链表中,再返回新创建的指针。

 刚开始由于newnode指向的是NULL,即该链表为空,所以我们需要进行尾插操作,同时tail也指向新链表的第一个节点。

即:

但是要注意的是,此时我们newnode中的头结点,它的next是指向原链表中所在位置的下一个节点的,并非指向NULL,即:

​ 

你可能会觉得代码中该部分是多余的

​ 

但是这一步缺失这种算法的关键。

如果我们这时候的cur指向了题目描述中的val,此时cur就会跳过该节点。

并指向下一个节点,那么如果没有tail->next = cur;这一行代码

那么新链表中的tail将直接指向题目描述中的val。

所以我们必须加上此代码!!! 

当遇到此时的情况时,如果我们直接放回newnode,就会是一个不完整的链表,因为尾结点并没有指向NULL,所有我们务必要在最后加上一句:tail->next = NULL;

 这种创建新链表的思想需要我们去学习,在之后的题目中尤为重要!

题目二:《反转链表》

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

对于本题目我将给出两种算法,为了展示出创建新链表该种算法的优势。 

解法一:三指针法

 如果我们尝试常规解法来实现,那我们我们就务必需要保存前后节点的位置。

所以该算法实现:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 
 //三指针法
struct ListNode* reverseList(struct ListNode* head) {
    if(head==NULL)
    {
        return NULL;
    }
    
    struct ListNode* n1 = NULL,*n2 = head,*n3 = head->next;
    if(n3 == NULL)
    {
        return n2;
    }

    while(n2 != NULL)
    {
        n2->next = n1;
        n1 = n2;
        n2 = n3;
        if(n3)
            n3 = n3->next;
    }
    return n1;
}

​ 

​ 

​ 

这道题还要注意,如果链表只要一个节点或者无节点时的返回值!

解法二:头插法 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

 //头插法
struct ListNode* reverseList(struct ListNode* head) {
    if(head == NULL)
    {
        return NULL;
    }

    struct ListNode* newnode = NULL;
    struct ListNode* cur = head;
    struct ListNode* next = head->next;
    
    while(next)
    {
        cur->next = newnode;
        newnode = cur;
        cur = next;
        next = next->next;
    }
    cur -> next = newnode;
    newnode = cur;
    return newnode; 

}

 

反转的本质,就是在新链表中头插 。

那么我们就可以将cur->next指向newnode;

newnode再指向此时的cur,这就完成了头插操作

再将cur = next,

next = next -> next;

因为我们改变来cur->next的指向,所以我们对于保存cur下一个节点的位置就尤为重要!

​ 

完成操作后,我们最好可以将head = NULL,避免出现野指针。

题目三: 《相交链表》

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode* curA = headA, *curB = headB;
    int countA = 0;
    int countB = 0;
    //判断是否相交
    while(curA->next)
    {
        curA = curA->next;
        countA++;
    }   

    while(curB->next)
    {
        curB = curB->next;
        countB++;
    }   
    if(curA != curB)
    {
        return NULL;
    }

    //找出相交的起始节点
    int n = abs(countA - countB);
    if(countA > countB)
    {
        while(n)
        {
            headA = headA->next;
            --n;
        }
        while(headA != headB)
        {
            headA = headA->next;
            headB = headB->next;
        }
        return headA;
    }
    else
    {
        while(n)
        {
            headB = headB->next;
            --n;
        }
        while(headA != headB)
        {
            headA = headA->next;
            headB = headB->next;
        }
        return headB;
    }


}

对于该题目,我们提供一种算法:

1.先判断它们是否相交。

2.找到第一个公共节点。

相交好判断

我们可以先遍历,找到它们最后一个节点,如果节点相同,就说明它们相交!

因为相交链表只能是“Y”型相交,而绝对不可能是“X”型的 !

那么对于第二步,

我们可以先求出两个链表分别有多长,再相减求绝对值,得出相差步。

再使得短的链表的curA先走相差步,这样两个指针就是从同一位置起步了

再一起同时走一步,直到它们相等,如果这时两指针相等,则就说明相等的节点就是第一个公共节点!

让curB走向差步:

​ 

在同时走一步:

​ 

如此就可以得到公共节点!

题目四:《合并两个有序数列》

 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

​ 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) 
{
    struct ListNode* cur1 = list1,*cur2 = list2;
    struct ListNode* newnode = (struct ListNode*)malloc(sizeof(struct ListNode));
    newnode->next = NULL;
    struct ListNode* next = NULL;
    struct ListNode* tail = newnode;
    while(cur1 && cur2)
    {
        if((cur1->val <= cur2->val))
        {
            next = cur1->next;
            tail->next = cur1;
            cur1 = next;
            tail = tail->next;
        }
        else
        {
            next = cur2->next;
            tail->next = cur2;
            cur2 = next;
            tail = tail->next;
        }
    }
    if(cur1==NULL)
    {
        tail->next = cur2;
    }
    else
    {
        tail->next = cur1;
    }
    return newnode->next;
}

对于该题目,我建议使用新链表法,同时我们最好创建一个哨兵位的头结点。

具体为什么我这里建议使用新链表法,想要反驳的同学下去可以自己动手创建一个无哨兵位的解法,相信你一定会被绕晕的。

鉴于我们已经学会了前面两道题目的算法,这道题相信大家一定很好理解!

​ 

 

 

如此循环,当cur1或者cur2为NULL时,则直接让tail->next指向cur1或cur2.

即:

题目五:《链表中倒数第K个节点》

 链表中倒数第k个结点_牛客题霸_牛客网

 

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */

/**
 * 
 * @param pListHead ListNode类 
 * @param k int整型 
 * @return ListNode类
 */
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
    // write code here
    if(pListHead == NULL)
    {
        return NULL;
    }

    int count = 0;
    struct ListNode* tmp = pListHead;
    while(tmp)
    {
        count++;
        tmp = tmp->next;
    }

    int n = count - k;
    if(n<=0 && k > count)
    {
        return NULL;
    }
    while(n--)
    {
        
        pListHead = pListHead->next;
    }
    return pListHead;

}

该题目的算法实现还是好理解 

我们先统计该链表存在多少个节点。

然后再减去所谓的倒数第K个。

就可以得到正数第几个n,

再将pListHead进行遍历,同时n--

再返回此时的pListHead

思路还是好理解的,在这里我就不进行画图展示了。

题目六:《链表的分割》

链表分割_牛客题霸_牛客网

​ 

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
#include <cstddef>
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x)
     {
        // write code here
        struct ListNode* head1,*tail1,*head2,*tail2;
        head1 = tail1 = (struct ListNode*)malloc(sizeof(struct ListNode));
        head2 = tail2 = (struct ListNode*)malloc(sizeof(struct ListNode));
        struct ListNode* cur = pHead;
        while(cur)
        {
            if(cur->val<x)
            {
                tail1->next = cur;
                tail1 = tail1->next;
                
            }
            else 
            {
                tail2->next = cur;
                tail2 = tail2->next;
            }
            cur= cur->next;
        }

        tail1->next = head2->next;
        //防止成环
        tail2->next = NULL;
        pHead = head1->next;
        free(head1);
        free(head2);
        return pHead;
    }
};

 对于该题目的算法思路,要注意的有以下几点:

1.我们在此选择开辟两个哨兵位的头节点创建链表,小于等于x的到第一个链表,大于x的到第二个链表。

2.再将小链表的最后一个节点的next,链接到第二个哨兵位头节点的next。

3.同时还要注意成环问题!

 

如此一直循环:

​ 

到这里时我们就可以直接将tail1->next = head2->next;

即:

此时一定不要忘记将tail2->next = NULL;

因为此时的tail2->next是指向的tail1指向的节点的

​ 

如果这里不注意的话,就会形成一个环!!!

​ 

如此才是正确的全部思路。

题目七:《链表的回文结构》 

链表的回文结构_牛客题霸_牛客网

 

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:
    bool chkPalindrome(ListNode* A) {
        // write code here

        //找中间节点
        ListNode* fast = A;
        ListNode* slow = A;
        while(fast && fast->next)
        {
            fast = fast->next->next;
            slow = slow->next;
        }

        //逆序
        ListNode* next = slow ->next;
        ListNode* rehead = slow;
        rehead->next = NULL;
        while(next)
        {
        slow = next;
        next = slow->next;
        slow->next = rehead;
        rehead = slow;
        }

        while(A && rehead)
        {
            if(A->val == rehead->val)
            {
                A = A->next;
                rehead = rehead->next;
            }
            else
            {
                return false;
            }
        }
        return true;
    }
};

 由于牛客网对于本题目只要C++一种格式,但是没关系,C++兼容C语言。

所有我们就按照我们的写法即可:

 

第一步,利用快慢指针找到中间节点!

即:

​ 

此时的该节点就为中间节点。

再逆序中间节点后面的全部节点

利用新链表法!

先创建个指针rehead

​ 

在创建的时候,提前将slow指向的节点拿下来,进行置空操作,即:

 再进行一个经典的头插操作即while循环里面的全部操作:

如此就可以进行全部逆序的操作,则此时的图为:

​ 

我们只需要分别将A和rehead每次挪动一步,再判断是否为相等即可。

如果一直相等直到循环结束,就return true

如果出现不想等的,直接return false

题目八:《环形链表(一)》 

 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode *head) {
    struct ListNode* fast,*slow;
    fast = slow = head;
    while(fast && fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
        if(fast == slow)
        {
            return true;
        }
    }
    return false;
}

对于一个带环链表,我们遇到该种题目应当先考虑考虑快慢指针算法。

如图:

fast一次走两步,slow一次走一步,当它们相遇的时候,一定是在圆环内!

例:

从上述可以看出,再进行第三次循环的时候,fast和slow就相遇,就说明此时的链表是带环链表。

 题目九:《环形链表(二)》 

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode* fast = head, *slow = head;
    struct ListNode* meet = NULL;
    while(fast && fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
        if(fast == slow)
        {
            meet = slow;
            while(head != meet)
            {
                head = head->next;
                meet = meet->next;
            }
            return head;
        }
    }

    return NULL;
}

这道题与上题类似,但区别在于现在已经告诉你这是一个环形链表,需要你求出进入环的第一个节点。

对于解决该问题的方法,此方法偏向于数学思维思路。

我们由图来分析。

由题目八引出结论:

 我们在题目八中分析过,如果我们利用快慢指针,就可以求出它们是否再圆环内。

但是当快指针一次走三步呢?

那么还可以追上吗?

这就不得不利用数学思维来解决此问题。

 

我们可以将链表抽象为如图内容。

那么当fast一次三步时,怎么判断它们是否相遇:

当slow刚进入环内时,fast肯定比slow快3倍,走过的距离肯定也多三倍。

但是一旦它们都在环内时,距离就会一直-2.

假设一开始的距离为n

此时的-1就代表了它们的距离相差1,意思就是:

那么就不难的出以下结论:

假设C为圆的周长,此时它们距离就是C-1。

如果C-1为偶数,那么随着它们-2的操作,最后会相遇。

但如果C-1是奇数,那么随着它们-2的操作,最后还需要再来一圈才可以相遇!

即:

1.若n为偶数,直接就可以追上

2.若n是奇数,C是奇数,得过两圈才能追上。

3.如果n是奇数,C是偶数,永远都追不上。

但是第3条是不成立的,因为我们可以得出公式:

L为直线长

N是两指针在刚开始的距离,

3L = L +n*C - N

即2L = n*C - N

等号左边百分百为偶数,

而右边永远等于奇数。

所以它们不相等,即该结论永远不成立!

对于第九题的算法:

 而对于该题目,我们只需要知道此时的fast只走一步,而它们绝对可以在圆环内相遇:

我们在它们相遇的地方创建个指针,指向该地方,后面我们就会用到此指针:

我们在创建个未知数X,代表第一个环节点到相遇点, 

 通过该图,我们可以知道,slow走过的路程 = fast的路程/2

所以就有2(L+X) = L + X + n*C

假设这个环足够小,那么我的fast很有可能在圆环内走很多圈,但我们假设就走过一圈。

则就有以下算式:

2(L+X) =L + X + C

L = C - X

通过以上的推导:

我们知道了以下:

L== Y

那我们就可以让meet和head同时走一步,直到它们相遇,因为相遇的地方就是圆环的第一个节点。

这样就可以求出来第一个节点了!

总结:

本题目设计到的数学思维和思路会使很多同学绕不清楚,还有转不过弯来。

对于这部分的解法下来需要好好熟练掌握并学习学习,在这里我就不再多讲了。

题目十:《随机链表的复制》

 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

/**
 * Definition for a Node.
 * struct Node {
 *     int val;
 *     struct Node *next;
 *     struct Node *random;
 * };
 */

struct Node* copyRandomList(struct Node* head) {
     if (head == NULL) {
        return NULL;
    }

	struct Node* cur = head;
    struct Node* copy = NULL;
    while(cur)
    {
        copy = (struct Node*)malloc(sizeof(struct Node));
        copy->val = cur->val;
        copy->next = cur->next;
        cur->next = copy;
        cur = cur->next->next;
    }
    copy = head->next;
    struct Node* tmp = NULL;
    cur = head;
    while(cur)
    {
        tmp = cur->next;
        tmp->random = (cur->random != NULL)?cur->random->next : NULL;
        cur = cur->next->next;
    }

    tmp = copy;
    while(tmp->next != NULL)
    {
        tmp->next = tmp->next->next;
        tmp = tmp->next;
    }
    return copy;
}

本道题目较难,我在这里先讲解以下思路:

1.先拷贝各个节点,再连接起来

2.对random进行赋值

 这里格外要注意,如果此时原radom是NULL,就要另外讨论。

如果不为空,则将cur->radom->next赋给copy

这一句代码则是精华所在!

3.断开连接

 将拷贝好的各个节点互相链接,并且返回。

总结:

本周的好题分享设计到的知识面较广,我们在做题过程中难免会遇到一些难以实现的操作,但是只要我们沉下心来一点点的了解和学习,相信一定会有进步!

记住“坐而言不如起而行!”

Action speak louder than words!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1204851.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vmware 修改主机名称 hadoop 服务器环境配置(一)

如何在虚拟机配置主机名称&#xff1a; 1. 如图所示在/etc 文件夹下有个hosts文件。追加映射关系&#xff1a; #关系 ip地址 名称 192.168.164.20 hadoop20 2. 保存后&#xff0c;重启reboot即可

炸裂!Sklearn 的 10 个宝藏级使用方法!

大家好&#xff0c;本次给大家介绍10个Sklearn方法&#xff0c;比较小众但非常好用。 1️.FunctionTransformer 虽然Sklearn中有很多内置的预处理操作可以放进pipeline管道&#xff0c;但很多时候并不能满足我们的需求。 如果是比较简单并且通过一个函数可以实现需求的情况&…

考前须知-2024年上半年系统集成项目管理工程师

可以看看23年下半年软考集成考试的难度 一、考试时间安排&#xff1a; 集成考试一年会考2次&#xff0c;上半年一次、下半年一次。考试时间4h&#xff0c;分批进行 系统集成项目管理工程师教材共655页&#xff0c;分为23章。其中,前3章为信息化与系统集成基础知识的内容,第4章…

4.5 构建onnx结构模型-Reshape

前言 构建onnx方式通常有两种&#xff1a; 1、通过代码转换成onnx结构&#xff0c;比如pytorch —> onnx 2、通过onnx 自定义结点&#xff0c;图&#xff0c;生成onnx结构 本文主要是简单学习和使用两种不同onnx结构&#xff0c; 下面以pow 结点进行分析 方式 方法一&am…

C语言之初阶指针

一、指针&#xff1a; 其实按照我的理解&#xff0c;当我们写c语言程序的时候&#xff0c;创建的变量&#xff0c;数组等都要在内存上开辟空间。而每一个内存都有一个唯一的编号&#xff0c;这个编号也被称为地址编号&#xff0c;就相当于&#xff0c;编号地址指针。 二、指针…

STM32F4 GPIO端口二极管作用——二极管钳位作用

如上图所示&#xff0c;有两个保护二极管&#xff0c;用于保护内部电路&#xff0c;防止I\O引脚外部过高或者过低的电压输入时造成内部电路损坏。 具体来讲&#xff1a;当引脚输入电压高于VDD时&#xff0c;上面的二极管导通&#xff0c;输入点电压被钳位到约VDD0.7V&#xff…

python打包部署脚本

linux可使用expect来实现自动交互&#xff0c;windows想要写出同样的功能脚本&#xff0c;只能使用python或者安装ActiveTcl 1、安装python Microsoft Store搜索python直接安装&#xff0c;默认会直接添加到环境变量https://www.python.org/官网下载&#xff0c;点击安装时会提…

比尔·盖茨谈他对软件应用和人工智能代理未来的见解

比尔盖茨在他的 Gatesnotes 网站中发表了一篇文章&#xff0c;分享了他对软件应用和人工智能代理未来的见解。他认为人工智能代理将大行其道&#xff0c;在接下来的五年里&#xff0c;这将完全改变。你不需要为不同的任务使用不同的应用程序。你只需用日常语言告诉你的设备你想…

基于Python优化图片亮度与噪点

支持添加噪点类型包括&#xff1a;添加高斯噪点、添加椒盐噪点、添加波动噪点、添加泊松噪点、添加周期性噪点、添加斑点噪点、添加相位噪点&#xff0c;还提供清除噪点的功能。 我们先看一下实测效果&#xff1a;&#xff08;test.jpg为原图&#xff0c;new.jpg为添加后的图片…

基于JavaWeb+SSM+校园零售商城微信小程序系统的设计和实现

基于JavaWebSSM校园零售商城微信小程序系统的设计和实现 源码获取入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 前言 摘 要 在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应…

HRNet关键点检测

HRNet是一种用于关键点检测的网络架构&#xff0c;它具有一些优点和缺点。 优点&#xff1a; 可以保持高分辨率&#xff1a;HRNet将高分辨率到低分辨率的子网并联连接&#xff0c;而不是像大多数现有解决方案那样串联连接。因此&#xff0c;HRNet能够保持高分辨率&#xff0c…

动态修改hosts

前言 因工作需要频繁变更hosts&#xff0c; 故须自己实现一个动态管理器&#xff0c; 市面上其实已经有了类似的软件&#xff0c;比如switchhosts!但因为不好集成其他功能&#xff08;如远程连接KVM&#xff09;&#xff0c;所以还是决定自己开发一套。 原理 使用之前强烈建…

tcpdump抓包的字节数量与ethtool统计数据不同的原因

情况介绍 在进行RDMA抓包流量分析时&#xff0c;我使用ethtool工具统计了RDMA网卡的流量发送数据数量&#xff0c;然后使用tcpdump进行抓包。 经过分析发现&#xff0c;tcpdump得到的数据数量总是大于ethtool得到的数据数量&#xff0c;而且每个数据包会多出4个字节。 分析 …

Juniper PPPOE双线路冗余RPM配置

------------------ 浮动静态路由 set routing-options static route 0.0.0.0/0 next-hop pp0.0 qualified-next-hop pp0.1 preference 10 ----------------- RPM测试的内容,包括从哪个接口发起测试,测试ping等等 #指定探针类型用ICMP请求 #探测的目标地址 #探测间隔 #探测阈…

Java第十八章Swing程序设计

一、Swing概述 Swing 是 Java 平台的用户界面&#xff08;UI&#xff09;工具包&#xff0c;它是一种现代化的、跨平台的 UI 工具包&#xff0c;可以使用各种操作系统上的 Java 虚拟机&#xff08;JVM&#xff09;来实现&#xff0c;包括 Windows、Linux 和 MacOS 等。Swing 提…

CopyOnWriteArrayList内存占用过多

目录 一、CopyOnWriteArrayList二、CopyOnWriteArrayList的适用场景三、CopyOnWriteArrayList内存占用过多的解决方法四、CopyOnWriteArrayList.add()源码分析 大家好&#xff0c;我是哪吒。 一、CopyOnWriteArrayList CopyOnWriteArrayList是Java中的一个线程安全的ArrayLis…

docker小技能

文章目录 I 预备知识Docker组成命名空间 (进程隔离)II 常用命令2.1 案例:流水线docker 部署2.2 删除没有使用的镜像2.3 shell 不打印错误输出2.4 阿里云流水线/jenkins忽略shell步骤中的报错https://www.runoob.com/docker/docker-architecture.html I 预备知识 Docker组成…

ElementUI表格el-table自适应高度(表头表尾固定不动)

ElementUI表格el-table自适应高度&#xff08;表头表尾固定不动&#xff09;&#xff0c;内容只在中间滚动&#xff0c;效果如图&#xff1a; 实现代码 <div class"mt-10" :style"{height:tableHeight}"><div class"operation-bar">…

15年之后再回低价的双十一,几分像从前?

文 | 螳螂观察 作者 | 易不二 今年双十一&#xff0c;全网铺天盖地的“低价”字眼&#xff0c;让人有种时空错乱的感觉。 犹记得&#xff0c;2009年双十一也是以一刀直砍到5折的低价&#xff0c;推开了一扇新世界的大门。在那个车马邮件还有网速都很慢的年月&#xff0c;人们…

深入理解强化学习——马尔可夫决策过程:随机过程和马尔可夫性质

分类目录&#xff1a;《深入理解强化学习》总目录 下图介绍了强化学习里面智能体与环境之间的交互&#xff0c;智能体得到环境的状态后&#xff0c;它会采取动作&#xff0c;并把这个采取的动作返还给环境。环境得到智能体的动作后&#xff0c;它会进入下一个状态&#xff0c;把…