五道LeetCode《中等难度》的单链表题

news2024/11/19 23:28:50

五道单链表中等难度题型

  • 1. 剑指 Offer II 021. 删除链表的倒数第 n 个结点
    • 第一种解法(单指针):
    • 第二种解法(栈):
    • 第三种解法(双指针):
  • 2. 删除排序链表中的重复元素 II(重点)
    • 普通状态
    • 特殊状态(头结点重复时)
    • 特殊状态(删除尾结点时)
  • 3. 删除链表中的节点
  • 4. 重排链表
    • 思路一:
    • 思路二(寻找链表中点 + 链表逆序 + 合并链表)
  • 5. 剑指 Offer II 077. 链表排序(重点!)

1. 剑指 Offer II 021. 删除链表的倒数第 n 个结点

在这里插入图片描述
题目描述:

找到链表的倒数第n个结点,并删除该结点

三种解法:

第一种解法(单指针):

1.遍历链表,求出链表长度 L
2.链表长度 L 减去 n ,就是倒数第 n 个结点
3.找到倒数第 n 个结点的前驱结点,让前驱结点的 next 指向倒数第 n 个结点的后一个结点。
4.倒数的n个结点的前驱结点,就是 L-n+1
5.因为如果要删除的是头节点,要删除的头节点没有先驱结点,所以设置一个哨兵位
6.哨兵位的 next 指向 head ,这样头结点删除的情况也被转化为了通用情况

在这里插入图片描述

代码如下:

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
    			
        ListNode dummy = new ListNode(0, head);//设置哨兵位
        int length = getLength(head);//求出链表长度
        ListNode cur = dummy;//用cur去遍历
        //遍历L-n+1次就是要删除结点的前驱结点
        for (int i = 1; i < length - n + 1; ++i) {
            cur = cur.next;
        }
        //前驱结点的next指向要删除结点的后一个结点
        cur.next = cur.next.next;
        return dummy.next;
    }
		//求出链表长度
    public int getLength(ListNode head) {
        int length = 0;
        while (head != null) {
            ++length;
            head = head.next;
        }
        return length;
    }
}

作者总结:

如果要删除的结点是最后一个结点,那么该代码的时间复杂度会达到 2×n ,虽然不是很慢,但是依旧没有达到想要的效果。

复杂度分析:

  • 时间复杂度O(n),其中 N 是给定链表中的结点数目。
  • 空间复杂度O(1)

第二种解法(栈):

实现思路:

我们可以在遍历链表的同时,顺便将链表中的结点依次存放到栈上,根据栈「先进后出」的原则,我们栈中弹出的第n个结点,就是我们要删除的结点,并且目前栈顶的节点就是待删除节点的前驱节点。这样一来,删除操作就变得十分方便了。

具体实现:

1.创建一个栈,将链表中的结点依次压入栈中
2.当链表遍历完成之后,依次从栈中弹出结点,到第n个结点时,就是我们要删除的结点
3.由于当前栈顶的结点刚好时第n个结点前驱结点,所以将栈顶的结点的next指向第 n 个结点的 next 就可以
4.由于需要考虑要删除的是头节点,所以我们设置一个哨兵位,这样即使要删除的结点是头节点,处理方法也和普通结点一样。

如图:

在这里插入图片描述

代码如下:

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0, head);//创建哨兵位
        Deque<ListNode> stack = new LinkedList<ListNode>();//创建一个栈
        ListNode cur = dummy;//cur代替哨兵位遍历
        while (cur != null) {
        //依次放入
            stack.push(cur);
            cur = cur.next;
        }
        //弹出倒数n个结点
        for (int i = 0; i < n; ++i) {
            stack.pop();
        }
        //当前栈顶就是要删除结点的前驱结点
        ListNode prev = stack.peek();
        //
        prev.next = prev.next.next;
        return dummy.next;
    }
}

作者总结:

栈最大的特点是先进后出,所以逆序输出是栈经常用到的一个应用场景。首先把所有元素依次入栈,然后把所有元素出栈并输出,这样就实 现了逆序输出。

复杂度分析:

  • 时间复杂度O(n),其中 N 是给定链表中的结点数目。
  • 空间复杂度O(n),其中 N 是链表的长度,主要为栈的开销。

第三种解法(双指针):

解题思路:

通过双指针,由于是删除倒数第 n 个结点,所以我们可以用距离的差,快指针先走 n+1 步,接下来两个指针一起走,当快指针为空时,此时的慢指针就是倒数第n-1个结点( n-1 是 n 的前驱结点)。

具体实现:

  1. 定义两个指针,curprev
  2. cur先走 n+1 步,然后两个指针一起向后遍历,直到cur为空时,此时prev就是要删除结点的前驱结点,prev.next=prev.next.next 就行。
  3. 定义一个哨兵位,使 curprev 最开始都指向 newHead

如图:
在这里插入图片描述
代码如下:

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
    //判断是否为空
        if(head==null) {
            return head;
        }
        //创建一个哨兵位
        ListNode newHead=new ListNode(0);
        //哨兵位的next指向head
        newHead.next=head;
        //将cur和prev同时指向newHead
        ListNode cur=newHead;
        ListNode prev=newHead;
		//快指针先走n+1步(也可以快指针总head走,走n步就可以,核心思路就是慢指针要和快指针之间的距离差1)
        for(int i=0;i<n+1;i++) {
            cur=cur.next;
        }
        //两个指针一起走
        while(cur!=null) {
            cur=cur.next;
            prev=prev.next;
        }
        //最后删除倒数第n个结点
        prev.next=prev.next.next;
        //返回newHead的next
        return newHead.next;
        
    }
}

作者总结:

不同于之前做的找到倒数第k个结点,该题是要删除倒数第k个结点,所以我们需要找到倒数第k个数的前驱节点,核心思路就是,快指针和慢指针最开始的距离差要为 n+1,不论是相同位置快指针先走 n+1 步,又或者慢指针是快指针的前一个结点,快指针走 n 步,最终要到达的目的都是和快指针的距离为 n+1,所以掌握核心思路,再去思考这道题就会很轻松。

复杂度分析:

  • 时间复杂度O(n),其中 N 是给定链表中的结点数目。
  • 空间复杂度O(1)

2. 删除排序链表中的重复元素 II(重点)

在这里插入图片描述

题目描述:

将有序链表中所有重复出现的数,都删除掉,只留下出现一次的数字。

需要考虑的事项:

  1. 考虑头删和尾删,
  2. 注意空指针异常,

一种普通状态:

1->2->3->3->4->4->5->null (中间删)

两种特殊状态:

1->1->1->2->3->null (头删)
1->2->3->3->3->null (尾删)

普通状态

在这里插入图片描述

解题思路:

  1. 定义三个指针,prev cur curNext
  2. 判断 cur 和 curNext 他们的 val 是否相等,如果不相等则把 cur 给 prev, curNext 给 cur,curNext=curNext.next.

如图:

在这里插入图片描述

重复上述操作,直到 cur.val == curNext.val

在这里插入图片描述

再次判断 curNext.val == cur.val 是否为真,如果为真,继续重复上述操作,

最后运行结果:

在这里插入图片描述

特殊状态(头结点重复时)

在这里插入图片描述

如果此时依旧是通过上述的代码运行,会爆出空指针异常的错误,因为的的 prev 是 null ,所以prev.next 就会产生空指针异常,解决的方法就是,判断是否是头删,如果是头删则 head=curNext,将头节点后移。

在这里插入图片描述

此时我们的头删就完成了

运行结果:

在这里插入图片描述

特殊状态(删除尾结点时)

在这里插入图片描述

这里需要注意空指针异常,具体细节如下

在这里插入图片描述
解决之后运行结果:

在这里插入图片描述
具体代码如下:

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head==null||head.next==null) {
            return head;
        }
        ListNode prev=null;
        ListNode cur=head;
        ListNode curNext=cur.next;
        while(curNext!=null) {
            //当他们的值不同时,集体后移,注意顺序
            if(cur.val!=curNext.val) {
                prev=cur;
                cur=curNext;
                curNext=curNext.next;
            } else {
                //当他们的值相同时,并且curNext不为空,进入循环
                //注意要将curNext!=null的判断条件写在左边
                //逻辑运算&&,先判断左边,如果左边为真才判断右边,
                //当你的curNext!=null写在右边时,
                //他会先进行curNext.val的操作,此时你的curNext已经为空
                //再去访问就会发出空指针异常
                while(curNext!=null&&cur.val==curNext.val) {
                    curNext=curNext.next;
                }
                //判断prev是否为空,如果为空就是头删
                if(prev!=null) {
                    //不为空将prev的next指向curNext
                    prev.next=curNext;
                } else {
                    //为空则头节点变成curNext
                    head=curNext;
                }
                //后续过程不变
                cur=curNext;
                //判断curNext是否为空,如果为空则不进行该操作
                if(curNext!=null)
                curNext=curNext.next;
            }
        }
        return head;
    }
}

作者总结

这道题主要考虑的是答题人的细心程度,有一点不注意就有可能会造成越界访问,所以需要时刻注意可能会爆出错误的地方,并且我们自己画图会对写这种编程题有很大的益处,它可以帮我们找到平时没有注意到的小问题。

复杂度分析:

  • 时间复杂度O(n),其中 N 是给定链表中的结点数目。
  • 空间复杂度O(1)

3. 删除链表中的节点

在这里插入图片描述
题目描述:

给你一个链表的结点,不能访问到头节点,要将链表的这个结点删除
用例如下:1->2->3->4->5->null node=3;
输出为:1->2->4->5->null

解题思路:

题目中提到了,我们无法访问到头节点,在平时我们删除结点,都是找到要删除结点的前驱结点,让前驱结点的next指向要删除结点的下一个结点。
在这里插入图片描述

但是题目直接给了要删除的结点,我们无法访问的它的前一个结点,我们可以考虑,将下一个结点的 val 和 next 都给要删除的结点,由于下一个结点的next给了我们的node所以我们找不到原来的node的下一个结点,自然就完成了删除,如果是C语言需要释放内存,则可以提前保存下一个结点,最后free().

如下图:
在这里插入图片描述

代码如下:

class Solution {
    public void deleteNode(ListNode node) {
        node.val=node.next.val;//替换为下一个结点的val
        node.next=node.next.next;//替换为下一个结点的next
	}
}

总结:

既然不能先删除自己,那就把自己整容成儿子,再假装自己就是儿子来养活孙子

复杂度分析:

  • 时间复杂度O(1)
  • 空间复杂度O(1)

4. 重排链表

在这里插入图片描述

题目描述:

大概意思就是:
在这里插入图片描述

解题思路:

思路一:

单链表并不支持随机访问,也不支持从后往前遍历,所以我们可以创建一个顺序表,将单链表中的结点一个一个存入顺序表中,最后根据下标来找到结点并重建链表。

具体实现:

  1. 构建一个顺序表
  2. 将链表存入到顺序表中
  3. 建立一个哨兵位,将后续重新排序的结点一个一个衔接在后面

代码如下:

class Solution {
    public void reorderList(ListNode head) {
        if(head==null||head.next==null) {
            return;
        }
        //利用顺序表存储,然后按指定位置
        //我这里没有直接使用库的顺序表,
        ListNode [] array=new ListNode[50000];
        ListNode cur=head;//
        int i=0;
        //从0下标存入
        while(cur!=null) {
            array[i]=cur;
            cur=cur.next;
            i++;
        }
        //最后i是元素个数
        ListNode newHead=new ListNode(0);
        ListNode newPrev=newHead;
        int a=0;//a是下标
        int b=i-1;//b也是下标,i是元素个数,元素个数-1就是最后一个元素的下标
        int count=1;//根据奇偶判断读取哪个下标的元素
        //最后i+1就是链表的结点个数+1,
        //count是从1开始的,所以当count=i+1时,就代表读取完了所有结点
        while(count!=i+1) {
        //如果是奇数,就顺序读取
            if(count%2!=0) {
               newPrev.next=array[a];
               newPrev=newPrev.next;
                a++;//
            } else{
            //如果是偶数就逆序读取
                 newPrev.next=array[b];
                 newPrev=newPrev.next;
                 b--;
        }
        count++;
    }
    //将左后一个结点呢next置为kong,防止循环
       newPrev.next=null;
       //将头节点改为newHead的next
        head=newHead.next;
    }
}

复杂度分析:

  • 时间复杂度O(n),n是链表的长度
  • 空间复杂度O(n),n是顺序表的长度

思路二(寻找链表中点 + 链表逆序 + 合并链表)

思路二:

通过找到链表的中点,从中点将链表逆序,此时的实现和判断回文链表很是相似!将链表逆序后,一个结点从头开始,一个结点从逆序的链表的头开始,依次向后遍历,最后利用哨兵位合并这个链表

如图:

在这里插入图片描述
注意:

我们需要考虑的是合并链表的退出条件,如果是奇数个结点的链表,我们采取cur!=prev,就会导致最后一个中间结点没有被合并到新链表中,所以需要单独考虑

具体步骤:

  1. 找到中间结点
  2. 逆序包含中间及后面的所以结点
  3. 合并单链表

代码如下(注意注释)

class Solution {

     public void reorderList(ListNode head) {
     if(head==null||head.next==null) {
             return;
         }
        //找到中间结点
        ListNode prev=head;//慢指针
        ListNode cur=head;//快指针
        while(cur!=null&&cur.next!=null) {
            cur=cur.next.next;
            prev=prev.next;
        }
        //逆序单链表
        cur=reverse(prev);
        prev=head;//prev从头遍历
        ListNode newHead=new ListNode(0);
       ListNode newPrev=newHead;
        int i=1;//来判断调用谁的结点
        while(true) {
            if(i%2!=0) {
               newPrev.next=prev;//衔接该结点
             //当两个结点相等时退出循环
               if(prev==cur) {
               //并将newPrev置为下一个结点
            		newPrev=newPrev.next;
                  	 break;
               }
               prev=prev.next;//prev指向下一个结点
            } else {
           	  newPrev.next=cur;//衔接该结点
           	 //当两个结点相等时退出循环
           	 if(prev==cur) {
           	 //并将newPrev置为下一个结点
           		newPrev=newPrev.next;
             	   break;
          	  }
            	cur=cur.next;//cur指向下一个结点
            }
            i++;
            newPrev=newPrev.next;//置为下一个结点
        }
        newPrev.next=null;//将尾结点的next置为null,防止循环

     }
     //逆置链表函数
    public ListNode reverse(ListNode head) {

        ListNode prev=null;
        ListNode cur=head;
        while(cur!=null) {
        ListNode curNext=cur.next;
        cur.next=prev;
        prev=cur;
        cur=curNext;
        }
        return prev;
    }

作者总结:

这道题作者最开始做的时候也没有思路,但是通过画图,也就慢慢的有了思路,关于我合并链表中,退出循环的条件,大家可以画图看一下,对应着图才能更好的掌握规律,包括作者为什么要将 if ( prev == cur ) 写在prev=prev.next或cur=cur.next的前面,大家可以画图思考一下,总之就是多画图,多思考,多上手敲代码。

复杂度分析:

  • 时间复杂度O(n),n是链表的长度
  • 空间复杂度O(1)

5. 剑指 Offer II 077. 链表排序(重点!)

在这里插入图片描述

题目描述:

给你一个无序链表,你需要将该链表排序

解题思路:

以链表的第一个结点为有序结点,后续结点和该有序链表的头进行对比,如果比头节点小,那就进行头插,如果比有序链表的尾小,那就尾插,否则就是中间插入。

如图:

在这里插入图片描述

我们先把会用到的指针都列举出来

  ListNode cur=head.next;//后续链表的头指针
  
  ListNode newhead=head;//当前有序链表的头指针
  
  newhead.next=null;//与后续链表断开联系
  
  ListNode prev=newhead;//有序链表向后遍历指针的前驱指针
  
  ListNode prevNext=newhead.next;//用于有序链表向后遍历的指ListNode last=newhead;//尾结点
  
  ListNode curNext=cur.next;//用于找回后续链表的指针

具体实现:

  1. 先将链表分割为一个有序链表,和一个无序链表
  2. 有序链表的头结点和无序链表中cur指向的结点进行对比,如果头节点小于cur对应的结点,就进行头插
  3. 有序链表的尾结点和无序链表中的cur指向的结点进行对比,如果 尾结点小于cur对应的结点,那就代表这个链表没有比这个结点还要大的结点了,所以直接尾插就好了!
  4. 其余情况就是中间插入了,我们通过找到第一个比cur对应的结点的大的结点,将cur插入在该结点前面,完成中间插入
  5. 完成了插入后,让 prev 重新回归头节点的位置,即prev=newHead,让 prevNext 重新成为有序链表的第二个结点,即prevNext=prev.next;

插入过程:
(有小瑕疵,cur跟尾结点比较的过程忽略了,直接按顺序对比去了,但是大体思路是这样)
在这里插入图片描述

代码如下:

class Solution {
    public static ListNode sortList(ListNode head) {
        if (head == null || head.next == null) {
             return head;
         }
         ListNode cur=head.next;//后续链表的头节点
         ListNode newhead=head;//当前有序链表的头节点
         newhead.next=null;//与后续链表断开联系
         ListNode prevNext=newhead.next;//有序链表向后遍历的结点
         ListNode prev=newhead;//有序链表向后遍历结点的前驱结点
         ListNode last=newhead;//尾结点
         while(cur!=null) {
             //头插
             ListNode curNext =cur.next;
             if(newhead.val>=cur.val) {
                 cur.next=newhead;
                 newhead=cur;
             } else if(last.val<cur.val) {
             		//尾插
                 last.next=cur;
                 last=cur;
                 last.next=null;
             } else {//中间插入
             //找到大于等于cur.val的结点
                while(cur.val>prevNext.val) {
                //prev一直保存prevNext的前一个结点
                    prev=prevNext;
                    //prevNext置为它的下一个结点
                    prevNext=prevNext.next;
                }
                //将cur插入prev和prevNext之间
                prev.next=cur;
                cur.next=prevNext;
             }
             //重置prev
             prev=newhead;
             //重置prevNext
             prevNext=prev.next;
             //重置cur
            cur=curNext;
         }
         //返回新头节点
    return newhead;
   } 
}

作者总结:

这道题的主要思路就是,将第一个结点单独出来,一步一步和这个链表的后续结点进行对比,分别进行头插,尾插,中间插入,该题的难度并不简单,对于初学者来说。
并且这道题属于经常会考到的面试题,最优的解法可以将时间复杂度缩短到 O(nlogn),后续我在学习归并排序后,会优化该题解。

复杂度分析:

  • 时间复杂度O(n^2),n是链表的长度
  • 空间复杂度O(1)

删除链表倒数第n个结点oj
删除链表中的重复结点II
删除链表中的节点
重排链表
链表排序

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

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

相关文章

利用VGG16网络模块进行迁移学习实现图像识别

​ ImageNet虽然带有”Net“&#xff0c;但他不是一种深度神经网络模型&#xff0c;它是个数据集&#xff0c;斯坦福大学教授李飞飞带头建立&#xff0c;是目前图像分类、检测、定位的最常用数据集之一。该数据集含大量数据1500万图片&#xff0c;2.2万类别&#xff0c;真彩图&…

PPT免费放送|Zabbix峰会结束了?还有件儿事!

精彩的Zabbix峰会成功举办&#xff0c;这并不意味着学习交流结束&#xff0c;还有件儿事——17份PPT免费获取&#xff0c;网盘见文末。干货满满细细品味。也欢迎你留言评价&#xff01; 值得一提的是&#xff1a;峰会中有理有据说明&#xff1a;Zabbix支持信创。开源免费的Zab…

IBDP学生如何申请中国香港的大学?

作为世界上最具竞争力的城市之一&#xff0c;香港拥有一些亚洲乃至世界上最好的大学。当然&#xff0c;这也使得香港成为内地学生以及国际留学生最喜爱的留学目的地之一。中国香港的教育在很大程度上是模仿英国的教育体系&#xff0c;但本科课程通常是英国和美国体系的混合体。…

Android 中的广播机制

一、Android广播概念&#xff1a; 在Android中&#xff0c;有一些操作完成以后&#xff0c;会发送广播&#xff0c;Android系统内部产生这些事件后广播这些事件&#xff0c;至于广播接收对象是否关心这些事件&#xff0c;以及它们如何处理这些事件&#xff0c;都由广播接收对象…

(附源码)ssm日语学习系统 毕业设计 271621

基于ssm日语学习系统 摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对日语学习等问题&#…

MySQL——表的内容增删查改

文章目录表的增删改查一、Create1、单行全列插入2、多行数据指定列插入3、插入否则更新4、替换二、Retrieve&#x1f60a;(重点)2.1 select 列2.1.1 全列查询2.1.2 指定列查询2.1.3 查询字段为表达式2.1.4 为查询结果指定别名2.1.5 结果去重2.2 where查询2.3 结果排序2.4 筛选分…

【VC7升级VC8】将vCenter Server 7.X 升级为 vCenter Server 8 (下)—— 升级步骤说明

目录前文说明3. 第一阶段升级&#xff08;1&#xff09;点击【升级】&#xff08;2&#xff09;升级介绍&#xff08;3&#xff09;最终中用户许可协议&#xff08;4&#xff09;连接到源设备&#xff08;5&#xff09;VC7与ESXi 证书警告&#xff08;6&#xff09;vCenter Ser…

【Vue】各种loader的基本配置与使用

✍️ 作者简介: 前端新手学习中。 &#x1f482; 作者主页: 作者主页查看更多前端教学 &#x1f393; 专栏分享&#xff1a;css重难点教学 Node.js教学 从头开始学习 ajax学习 目录webpack中的loader  loader概述  打包处理css文件  打包处理less文件  打包处理图片  …

LWIP框架

目录 协议栈分层思想 1. 网络接口层 2. 网络层 3. 传输层 4. 应用层 进程模型 单进程模型 协议栈编程接口 1、Raw/Callback API 2、Netconn API 3、Socket API 协议栈分层思想 TCP/IP协议完整的包含了一系列构成互联网基础的网络协议&#xff0c;TCP/IP协议的开发出…

HTTP Digest Authentication 使用心得

简介 浏览器弹出这个原生的对话框&#xff0c;想必大家都不陌生&#xff0c;就是 HTTP Baisc 认证的机制。 这是浏览器自带的&#xff0c;遵循 RFC2617/7617 协议。但必须指出的是&#xff0c;遇到这界面&#xff0c;不一定是 Basic Authentication&#xff0c;也可能是 Dige…

墨门云终端行为趋势报表,泄密风险提前预警

事件响应滞后&#xff0c;事后再补救&#xff0c;为时晚矣&#xff0c;据IBM的数据泄露成本报告显示&#xff0c;加强风险监测可更快发现数据泄露行为&#xff0c;有效降低企业的数据泄露成本&#xff0c;可见建立完善的风险预警响应机制&#xff0c;可以避免更大的损失&#x…

5G无线技术基础自学系列 | NSA组网场景下移动性管理

素材来源&#xff1a;《5G无线网络规划与优化》 一边学习一边整理内容&#xff0c;并与大家分享&#xff0c;侵权即删&#xff0c;谢谢支持&#xff01; 附上汇总贴&#xff1a;5G无线技术基础自学系列 | 汇总_COCOgsta的博客-CSDN博客 NSA组网场景下移动性管理涉及的相关概念…

js操作二进制数据

使用ArrayBuffer对象保存二进制数据&#xff0c;使用TypedArray和DataView 视图来读写数据。 ArrayBuffer代码内存中的一段数据 const buff new ArrayBuffer(4)这样就创建了一个4(byte)字节的长度的内存判断&#xff0c;初始值都为0 注&#xff1a;一般中文占2个字节&#xff…

葡聚糖修饰Hrps共价三聚肽|葡聚糖修饰CdSe量子点

葡聚糖修饰Hrps共价三聚肽|葡聚糖修饰CdSe量子点 葡聚糖修饰Hrps共价三聚肽 中文名称&#xff1a;葡聚糖修饰Hrps共价三聚肽 纯度&#xff1a;95% 存储条件&#xff1a;-20C&#xff0c;避光&#xff0c;避湿 外观:固体或粘性液体 包装&#xff1a;瓶装/袋装 溶解性&am…

爆火的 ChatGPT 会让客服岗位消失吗?

近日&#xff0c;由 OpenAI 推出的 ChatGPT 在全球互联网爆火。具体有多火呢&#xff1f;根据 OpenAI 的 CEO Sam Altman 的说法&#xff1a;上周三才上线的 ChatGPT&#xff0c;短短几天&#xff0c;用户数已突破 100 万大关。 那么&#xff0c;ChatGPT 是什么呢&#xff1f;…

无线充电智能车的制作

本文素材来源于宁夏大学 作者&#xff1a;白二曹、王瑞、穆琴、王童兵 指导老师&#xff1a;康彩 一、项目简介 1.功能介绍 无线充电智能车由无线充电、自动控制、红外遥控、网页显示四部分组成。 &#xff08;1&#xff09;流程描述 用户端浏览器访问http://127.0.0.1页面…

Cy5.5 Tyramide,Cyanine5.5 Tyramide,花青素Cy5.5 酪酰胺化学试剂供应

一&#xff1a;产品描述 1、名称 英文&#xff1a;Cy5.5 Tyramide&#xff0c;Cyanine5.5 Tyramide 中文&#xff1a;花青素Cy5.5 酪酰胺 2、CAS编号&#xff1a;N/A 3、所属分类&#xff1a;Cyanine 4、分子量&#xff1a;738.4 5、分子式&#xff1a;C48H52CIN3O2 6、…

如何用DOS命令设置ip地址及DNS

用DOS命令设置ip地址及DNS 设置/修改IP地址&#xff0c;子网掩码&#xff0c;网关的格式&#xff1a; netsh interface ip set address "本地连接" static 10.25.35.35 255.255.255.0 10.25.35.7 auto[more] 命令的意思是将“本地连接” ip地址设置成 10.25.35.3…

SD NAND 的 SDIO在STM32上的应用详解(下篇)

七.SDIO外设结构体 其实前面关于SDIO寄存器的讲解已经比较详细了&#xff0c;这里再借助于关于SDIO结构体再进行总结一遍。 标准库函数对 SDIO 外设建立了三个初始化结构体&#xff0c;分别为 SDIO 初始化结构体SDIO_InitTypeDef、SDIO 命令初始化结构体 SDIO_CmdInitTypeDef…

Lq93:复原 IP 地址

有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 . 分隔。 例如&#xff1a;"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址&#xff0c;但是 "0.011.255.2…