【算法系列】链表

目录

常用技巧

常用操作

 leetcode/牛客题目

一、移除链表元素

二、反转链表

三、链表的中间结点

四、返回倒数第k个节点

五、合并两个有序链表

六、链表分割

七、链表的回文结构

八、相交链表

九、环形链表

十、环形链表 II

十一、随机链表的复制

十二、两数相加

十三、两两交换链表中的节点

十四、重排链表

十五、合并K个升序链表

十六、K个一组翻转链表


常用技巧

1.画图 --- 直观,便于理解,代码不容易出错

2.引入虚拟头节点(带哨兵位的头节点) --- 便于处理边界情况,方便对链表操作

3.不要吝啬空间,大胆去定义变量

如上图所示,要将cur插入到两个节点之间,那么①与②的顺序就不能颠倒,但是如果定义了一个指针变量next,就完全不用考虑链接顺序了!

①②③④可以任意颠倒~

4.快慢双指针~

比如判环,找链表中环的入口,找链表倒数第n个节点

常用操作

1.创建一个新节点

2.尾插

3.头插

 leetcode/牛客题目

一、移除链表元素

203. 移除链表元素 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/remove-linked-list-elements/description/

1.题目解析

删除链表中值为val的所有节点

2.算法分析

法一: 把所有值不等于val的节点进行尾插

法二: 在原链表进行删除操作

3.算法代码

法一: 把所有值不等于val的节点进行尾插

class Solution {
public:ListNode* removeElements(ListNode* head, int val) {ListNode* newHead = new ListNode(); //虚拟头节点ListNode* cur = head, *tail = newHead;while(cur){if(cur->val != val){tail->next = cur;tail = tail->next;cur = cur->next;}else{ListNode* next = cur->next;delete cur;cur = next;}}tail->next = nullptr;return newHead->next;}
};

法二: 在原链表进行删除操作

class Solution {
public:ListNode* removeElements(ListNode* head, int val) {ListNode* newHead = new ListNode(); //虚拟头节点newHead->next = head;ListNode* cur = head, *prev = newHead; //prev用于记录当前节点的前一个节点while(cur){if(cur->val == val){    prev->next = cur->next;delete cur;cur = prev->next;}else{prev = cur;cur = cur->next;}}return newHead->next;}
};

二、反转链表

206. 反转链表 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/reverse-linked-list/1.题目解析

反转链表

2.算法分析

法一:头插法

法二:三指针反转链表

3.算法代码

法一:头插法

class Solution {
public:ListNode* reverseList(ListNode* head) {ListNode* newHead = new ListNode();ListNode* cur = head;while(cur){ListNode* next = cur->next;cur->next = newHead->next;newHead->next = cur;cur = next;}ListNode* ret = newHead->next;delete newHead;return ret;}
};

法二:三指针反转链表

class Solution {
public:ListNode* reverseList(ListNode* head) {if(head == nullptr) return head;ListNode* n1 = nullptr;ListNode* n2 = head;ListNode* n3 = head->next;while(n2){//1.改变指针指向n2->next = n1;//2.循环迭代n1 = n2;n2 = n3;if(n3) n3 = n3->next;}return n1;}
};

三、链表的中间结点

876. 链表的中间结点 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/middle-of-the-linked-list/1.题目解析

返回链表的中间节点,如果有两个中间节点,返回第二个中间节点

2.算法分析
这类题目是典型的双指针解法,定义快慢指针,快指针每次走两步,慢指针每次走一步,当快指针走到空或者走到最后一个节点,慢指针指向的就是中间节点

3.算法代码

class Solution {
public:ListNode* middleNode(ListNode* head) {ListNode* fast = head, *slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;}return slow;}
};

四、返回倒数第k个节点

面试题 02.02. 返回倒数第 k 个节点 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/kth-node-from-end-of-list-lcci/1.题目解析

返回链表倒数第k个节点中的值

2.算法分析

法一:先遍历一遍链表,求出节点总个数n, 再从头遍历,  循环n-k次,求出倒数第k个节点的值

法二:快慢双指针策略

fast和slow指针开始都在起始位置,fast先走k步,然后slow和fast再一起走,每次都走一步,当fast走到空时,slow的位置就是倒数第k个节点

3.算法代码

法一:

class Solution {
public:int kthToLast(ListNode* head, int k) {ListNode* cur = head;int n = 0;while(cur){cur = cur->next;n++;}cur = head;for(int i = 0; i < n-k; i++){cur = cur->next;}    return cur->val;}
};

法二:

class Solution {
public:int kthToLast(ListNode* head, int k) {ListNode* slow = head, *fast = head;while(k--)fast = fast->next;while(fast){fast = fast->next;slow = slow->next;}return slow->val;}
};

五、合并两个有序链表

21. 合并两个有序链表 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/merge-two-sorted-lists/description/1.题目解析

将两个升序链表合并成1个升序的链表

2.算法分析

本题和合并两个有序数组非常相似,采用的方法都是遍历两个链表(数组), 每次取小的进行尾插

3.算法代码

class Solution {
public:ListNode* mergeTwoLists(ListNode* list1, ListNode* list2){if(list1 == nullptr) return list2;if(list2 == nullptr) return list1;ListNode* newHead = new ListNode(), *tail = newHead;ListNode* cur1 = list1, *cur2 = list2;while(cur1 && cur2){if(cur1->val <= cur2->val){tail->next = cur1;tail = tail->next;cur1 = cur1->next;}else{tail->next = cur2;tail = tail->next;cur2 = cur2->next;}}  if(cur1) tail->next = cur1;if(cur2) tail->next = cur2;ListNode* ret = newHead->next;delete newHead;return ret;}
};

六、链表分割

链表分割_牛客题霸_牛客网 (nowcoder.com)icon-default.png?t=N7T8https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70?tpId=8&&tqId=11004&rp=2&ru=/activity/oj&qru=/ta/cracking-the-coding-interview/question-ranking1.题目解析

给定一个值x, 将所有值小于x的节点排在其余节点之前

2.算法分析

我们只需要遍历一遍原始链表,将值小于x的节点尾插到一个新的链表中,将值>=x的节点尾插到另一个新的链表中,然后将前一个新的链表和后一个新的链表链接起来即可,但是为了方便处理,我们仍然给两个新的链表都添加了虚拟头节点

3.算法代码

class Partition {
public:ListNode* partition(ListNode* pHead, int x) {ListNode* greaterHead = new ListNode(-1), *greatertail = greaterHead;ListNode* lessHead = new ListNode(-1), *lesstail = lessHead;ListNode* cur = pHead;while(cur){if(cur->val < x){lesstail->next = cur;lesstail = lesstail->next;cur = cur->next;}else {greatertail->next = cur;greatertail = greatertail->next;cur = cur->next;}}lesstail->next = greaterHead->next;greatertail->next = nullptr;return lessHead->next;}
};

七、链表的回文结构

链表的回文结构_牛客题霸_牛客网 (nowcoder.com)icon-default.png?t=N7T8https://www.nowcoder.com/practice/d281619e4b3e4a60a2cc66ea32855bfa?tpId=49&&tqId=29370&rp=1&ru=/activity/oj&qru=/ta/2016test/question-ranking1.题目解析

判断链表是否是回文链表

2.算法分析

本题可以拆解成以下几个问题

1.求链表的中间节点

2.翻转中间节点以后的部分

3.判断前半部分链表和翻转后的后半部分链表是否相等

3.算法代码

class PalindromeList {
public:bool chkPalindrome(ListNode* A) {//1.找链表的中间节点ListNode* fast = A, *slow = A;while(fast && fast->next){fast = fast->next->next;slow = slow->next;}//2.翻转后半部分ListNode* newHead = new ListNode(-1);ListNode* cur = slow;while(cur){ListNode* next = cur->next;cur->next = newHead->next;newHead->next = cur;cur = next;}//3.判断两个链表是否相等ListNode* B = newHead->next;while(B){if(A->val != B->val)return false;A = A->next;B = B->next;}return true;}
};

八、相交链表

160. 相交链表 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/intersection-of-two-linked-lists/1.题目解析

求两个相交链表的相交的起始节点

2.算法分析

解法一:

1.分别遍历两个链表,求出两个链表的长度(节点的个数), 并求出长度差 gap

2.定义快慢指针,让fast指针指向较长链表的第一个节点,先走gap步

3.快慢指针同时向后走,当快慢指针相遇时,就是相交链表的起始节点

解法二:

3.算法代码

解法一:

class Solution {
public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {ListNode* cur1 = headA, *cur2 = headB;int lenA = 0, lenB = 0;while(cur1){cur1 = cur1->next;lenA++;}while(cur2){cur2 = cur2->next;lenB++;}ListNode* fast = headA, *slow = headB;if(lenA < lenB){fast = headB;slow = headA;}int gap = abs(lenA - lenB);while(gap--)fast = fast->next;while(slow != fast){slow = slow->next;fast = fast->next;}return slow;}
};

解法二:

class Solution {
public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB){ListNode* cur1 = headA, *cur2 = headB;while(cur1 != cur2){cur1 = cur1 != nullptr ? cur1->next : headB;cur2 = cur2 != nullptr ? cur2->next : headA;}  return cur1;}
};

九、环形链表

141. 环形链表 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/linked-list-cycle/1.题目解析

判断链表中是否有环

2.算法分析

定义快慢指针,快指针每次走两步,慢指针每次走一步,如果快慢指针可以相遇,说明链表中有环;如果fast指针走到了空/fast的下一个节点就是空,说明链表中不带环

简单证明: 如果有环,fast必然先进入环,slow后进入环,所以当slow即将入环时,假设相距x, 由于fast每次走两步,slow每次走一步,所以fast和slow之间的距离每次缩小1,因此最后距离总会减小到0,也就是相遇!

 拓展: fast每次走3步是不可以的,因为如果fast每次走3步,slow走1步,距离每次缩小2,如果x是偶数,那么x会减小到0,slow和fast相遇,但是如果x是奇数,那么距离会减小到1, -1 ...., 就会错过距离0, 因此本轮slow和fast没有相遇; 下一轮slow和fast相距N-1( N代表环的长度 ), 如果N是奇数,那么N-1是偶数,则本轮可以相遇;若N是偶数,N-1是奇数,则fast和slow永远都相遇不了!

3.算法代码

class Solution {
public:bool hasCycle(ListNode *head) {ListNode* fast = head, *slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;if(fast == slow) return true;}   return false;}
};

十、环形链表 II

142.环形链表 IIicon-default.png?t=N7T8https://leetcode.cn/problems/linked-list-cycle-ii/description/1.题目解析

如果链表不带环,返回nullptr, 如果链表带环,返回环形链表的第一个入环节点的指针

2.算法分析

如何判断链表是否带环,题目九已经讲解过了,因此我们接下来的关键就是求入环节点

法一: 快慢指针

如果有环, slow和fast必在环内相遇,此时再定义一个指针cur2, cur2从fast和slow相遇位置开始走,与此同时,cur1(原先链表的head)从头开始走,两个指针每次都走一步,当cur1和cur2相遇时,相遇的地方就是入环的第一个节点

简单证明:

法二: 转化成题目八 ---> 相交链表

如果有环, slow和fast必在环内相遇,此时可以将环断开,形成两个链表,此时问题就转化成了相交链表的问题了~

3.算法代码

法一:

class Solution {
public:ListNode *detectCycle(ListNode *head) {ListNode* fast = head, *slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;if(slow == fast) //一定有环{ListNode* cur1 = head, *cur2 = fast;while(cur1 != cur2){cur1 = cur1->next;cur2 = cur2->next;}return cur1;}}  return nullptr;}
};

法二:

​class Solution {
public://求相交链表的第一个交点ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {ListNode* cur1 = headA, *cur2 = headB;int lenA = 0, lenB = 0;while(cur1){cur1 = cur1->next;lenA++;}while(cur2){cur2 = cur2->next;lenB++;}ListNode* fast = headA, *slow = headB;if(lenA < lenB){fast = headB;slow = headA;}int gap = abs(lenA - lenB);while(gap--)fast = fast->next;while(slow != fast){slow = slow->next;fast = fast->next;}return slow;}ListNode *detectCycle(ListNode *head) {ListNode* fast = head, *slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;if(slow == fast) //一定有环{ListNode* head2 = fast->next;fast->next = nullptr; //断开,形成两个链表return getIntersectionNode(head, head2);}}  return nullptr;}
};

十一、随机链表的复制

138. 随机链表的复制 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/copy-list-with-random-pointer/description/

1.题目解析

题目给定一个链表,链表中除了有指向下一个节点的指针之外,还有指向链表中随机一个节点的指针random, 题目要求深拷贝原链表,并返回

2.算法分析

1.将所有的新节点链接到原节点后面

2.控制所有复制节点中的random指向

3.解开新链表和原链表绑定,恢复原链表

3.算法代码

class Solution {
public:Node* copyRandomList(Node* head) {//1.将所有的新节点链接到原节点后面Node* cur = head;while(cur){Node* next = cur->next; //先保存下一个节点Node* copy = new Node(cur->val); //开辟复制节点cur->next = copy; //将复制节点链接到原链表对应节点后面copy->next = next; //将下一个节点链接到复制节点的后面cur = next; //更新cur到下一个节点} //2.控制所有复制节点中的random指向cur = head;while(cur){Node* copy = cur->next; //找到复制节点if(cur->random == nullptr) //原节点的random为空,则复制节点的random为空{copy->random = nullptr; }else //原节点的random不为空,则复制节点的random指向cur->random->next{copy->random = cur->random->next;}cur = copy->next; //更新cur指针}//3.解开原链表和新链表的绑定,恢复原链表cur = head;Node* copyHead = NULL, *copyTail = NULL;  //copyHead记录复制链表的开始, copyTail记录复制链表的结尾while(cur){Node* copy = cur->next; //记录复制节点Node* next = copy->next; //记录原链表下一个节点if(copyTail == nullptr) //开始时copyTail为空{copyHead = copyTail = copy;}else{copyTail->next = copy; //链接复制链表两个相邻节点copyTail = copyTail->next; //更新copyTail指针}cur->next = next; //链接原链表的相邻两个节点cur = next; //更新cur指针}return copyHead;}
};

十二、两数相加

2. 两数相加 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/add-two-numbers/description/1.题目解析

两个单链表,每个链表存储了一个整数(逆序存储), 返回两数相加之后的结果(依旧是链表)

2.算法分析

题目中的逆序存储是为了方便我们操作,我们只需要从头开始向后遍历链表相加即可

解法就是模拟两数相加即可

3.算法代码

class Solution {
public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2){ListNode* head = new ListNode(); //创建虚拟头节点ListNode* cur1 = l1, *cur2 = l2, *tail = head;int t = 0; //记录当前位置相加结果while(cur1 || cur2 || t) //有可能当cur1和cur2都为空时,t中还保留了一个进位{if(cur1){t += cur1->val;cur1 = cur1->next;}if(cur2) {t += cur2->val;cur2 = cur2->next;}//链接新节点tail->next = new ListNode(t % 10);tail = tail->next;t /= 10; //进位情况}//释放虚拟头节点tail = head->next;delete head;return tail;}
};

十三、两两交换链表中的节点

24. 两两交换链表中的节点 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/swap-nodes-in-pairs/description/1.题目解析

两两交换链表中的节点, 但是不能直接交换节点中的值, 而是要改变指针指向

2.算法分析

2.1增加虚拟头节点,统一了交换1,2节点和交换后面两两节点的操作

2.2采用循环的方式完成整个过程

2.3 循环结束的条件是 cur为空或者 next为空

2.2所给图示是next为空就结束了,但是还有可能是cur为空结束~

3.算法代码

class Solution {
public:ListNode* swapPairs(ListNode* head){if(head == nullptr || head->next == nullptr) return head;ListNode* newHead = new ListNode();newHead->next = head;ListNode* prev = newHead, *cur = head, *next = head->next, *nnext = next->next;while(cur && next){//1.交换节点prev->next = next;next->next = cur;cur->next = nnext;//2.修改指针(注意顺序)prev = cur;cur = nnext;if(cur) next = cur->next;if(next) nnext = next->next;}cur = newHead->next;delete newHead;return cur;}
};

十四、重排链表

143. 重排链表 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/reorder-list/1.题目解析

按题目要求将链表节点重新排列顺序

2.算法分析

这题目可以拆成以下3个子问题~

1.找到链表的中间节点 --- 双指针

2.把后面的部分逆序 --- 头插法

3.合并两个链表 --- 双指针

注意:找到中间节点之后,我们可以逆序连同中间节点之后的部分,也可以逆序不包含中间节点之后的部分

但是我们逆序完之后需要形成两个链表,如果采用头插法逆序包含中间节点及以后的部分,那么链表就无法断开,因为我们没有办法得到mid的前一个节点地址prev,从而无法将prev的next置成空指针,而如果采用头插法逆序中间节点以后的部分, 断开链表只需要将mid->next置成空指针即可

如果一定要逆序包含mid及以后的部分,可以添加虚拟头节点,此时slow的落点就是上面的prev了!

3.算法代码

class Solution {
public:void reorderList(ListNode* head){//特殊处理,不需要重排if(head == nullptr || head->next == nullptr || head->next->next == nullptr) return;//1.找到链表的中间节点ListNode* slow = head, *fast = head;while(fast && fast->next){slow = slow->next;fast = fast->next->next;}//2.把slow后面的部分逆序ListNode* head2 = new ListNode();ListNode* cur = slow->next;slow->next = nullptr; //断开链表while(cur){ListNode* next = cur->next;cur->next = head2->next;head2->next = cur;cur = next;}//3.合并两个链表ListNode* ret = new ListNode(), *tail = ret;ListNode* cur1 = head, *cur2 = head2->next;while(cur1) //由于第一个链表一定比第二个链表长, 因此判断cur1即可{//尾插第一个链表tail->next = cur1;cur1 = cur1->next;tail = tail->next;//尾插第二个链表if(cur2){tail->next = cur2;cur2 = cur2->next;tail = tail->next;}}}
};

十五、合并K个升序链表

23. 合并 K 个升序链表 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/merge-k-sorted-lists/description/1.题目解析

将所有的升序链表合并成一个升序链表,并返回

2.算法分析

法一:暴力解法:链表两两合并,直至所有链表合并完成, 时间复杂度:  假设每个链表长度为n, 则时间复杂度为 O(n*(k-1) + n*(k-2) + ... +)  =  O(n*k^2)

法二:利用优先级队列优化暴力枚举策略

我们可以创建一个小堆,开始时将所有的链表头节点指针都放进去,然后创建一个新的虚拟头节点,出堆顶元素尾插,然后让堆顶元素指针的下一个节点指针进入堆,依次类推,  时间复杂度为O(n*k*logk)

法三:分治-递归

从中间劈开,如果左右部分已经合并完成,那么最后只需要合并左右两个链表即可,而左右链表如何合并的呢???和原问题是相同的,依旧从中间劈开,让左右部分合并完成即可

3.算法代码

法二:优先级队列

class Solution 
{
public://仿函数struct cmp{bool operator()(const ListNode* l1, const ListNode* l2){return l1->val > l2->val;}};ListNode* mergeKLists(vector<ListNode*>& lists){//创建小根堆priority_queue<ListNode*, vector<ListNode*>, cmp> heap; //小堆for(auto& l : lists) if(l) heap.push(l);//合并所有链表ListNode* newHead = new ListNode(), *tail = newHead;while(!heap.empty()){ListNode* top = heap.top();heap.pop();tail->next = top;tail = tail->next;if(top->next) heap.push(top->next);}return newHead->next;}
};

法三:分治-递归

class Solution 
{
public:ListNode* mergeKLists(vector<ListNode*>& lists){return merge_sort(lists, 0, lists.size()-1);}ListNode* merge_sort(vector<ListNode*>& lists, int left, int right){if(left > right) return nullptr;if(left == right) return lists[left];//1.求中间节点int mid = (left + right) >> 1;//2.递归左右区间ListNode* l1 = merge_sort(lists, left, mid);ListNode* l2 = merge_sort(lists, mid+1, right);//3.合并两个有序链表return merge_two_lists(l1, l2);}ListNode* merge_two_lists(ListNode* l1, ListNode* l2){if(l1 == nullptr) return l2;if(l2 == nullptr) return l1;ListNode* cur1 = l1, *cur2 = l2;ListNode* newHead = new ListNode(), *tail = newHead;while(cur1 && cur2){if(cur1->val <= cur2->val){tail->next = cur1;tail = tail->next;cur1 = cur1->next;}else  {tail->next = cur2;tail = tail->next;cur2 = cur2->next;}  }if(cur1) tail->next = cur1;if(cur2) tail->next = cur2;return newHead->next;}
};

十六、K个一组翻转链表

25. K 个一组翻转链表 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/reverse-nodes-in-k-group/1.题目解析

K个一组翻转链表,最后不够K个节点,就不用再翻转了~

2.算法分析

1.求出需要翻转多少组:n  ---> 链表节点总个数 / k 即可

2.重复n次, 长度为k的链表的翻转即可

3.算法代码

class Solution {
public:ListNode* reverseKGroup(ListNode* head, int k) {//1.求需要翻转多少组int n = 0;ListNode* cur = head;while(cur){cur = cur->next;n++;}n /= k;//2.重复n次,长度为k的链表的翻转ListNode* newHead = new ListNode(), *prev = newHead;cur = head;for(int i = 0;i < n; i++){ListNode* tmp = cur;for(int j = 0; j < k; j++){ListNode* next = cur->next;cur->next = prev->next;prev->next = cur;cur = next;}prev = tmp;}//把不需要翻转的节点接上prev->next = cur;return newHead->next;}
};

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

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

相关文章

【图像增强(空域)】基于灰度变换的图像增强及Matlab仿真

1. 摘要&#xff1a; 空域内的图像增强就是调整灰度图像的明暗对比度&#xff0c;对图像中各个像素的灰度值直接进行处理。常用的方法包括&#xff1a;灰度变换增强和直方图增强。 2. 原理&#xff1a; 灰度变换增强是空域ne对图像进行增强的一种简单且直接的方法。灰度变换…

使用CUDA的PyTorch进行张量重整化的gpu加速

使用CUDA的PyTorch进行张量重整化的gpu加速 摘要IntroductionAlgorithm and TorchTrg discussionModels and Results GPU-Acceleration of Tensor Renormalization with PyTorch using CUDA 摘要 作者展示了基于张量重整化群&#xff08;TRG&#xff09;方法的数值计算可以通过…

绝地求生:季后赛名额确定!NH战队总积分榜排名第一!

2024年5月5日&#xff0c;PCL春季赛常规赛第五阶段第三天比赛结束&#xff0c;今天打完春季赛常规赛结束&#xff0c;16个战队进入季后赛的名额已确定。NH战队总积分506分&#xff0c;总积分榜排名第一&#xff01;&#xff01;NH战队也是唯一一支总积分超过500分的队伍。今天最…

【前端】HTML实现个人简历信息填写页面

文章目录 前言一、综合案例&#xff1a;个人简历信息填写页面 前言 这篇博客仅仅是对HTML的基本结构进行了一些说明&#xff0c;关于HTML的更多讲解以及CSS、Javascript部分的讲解可以关注一下下面的专栏&#xff0c;会持续更新的。 链接&#xff1a; Web前端学习专栏 下面我对…

LLaMA 羊驼系大语言模型的前世今生

关于 LLaMA LLaMA是由Meta AI发布的大语言系列模型&#xff0c;完整的名字是Large Language Model Meta AI&#xff0c;直译&#xff1a;大语言模型元AI。Llama这个单词本身是指美洲大羊驼&#xff0c;所以社区也将这个系列的模型昵称为羊驼系模型。 Llama、Llama2 和 Llama3…

C++字模软件发送 单片机接收显示

/****先定义数组类型再赋值**L310*********/ /*2014 8 21 10:01**PAST*CODE1000**TEST**/ #include<reg51.h> #define uint unsigned int #define uchar unsigned char sfr AUXR0x8e; //辅助寄存器 sfr SADDR0xA9; …

多链路聚合设备是什么

多链路聚合设备属于通信指挥装备。 乾元通多链路聚合设备&#xff0c;它能够将多个网络链路聚合成一个逻辑链路&#xff0c;以实现高速、稳定、可靠的数据传输。多链路聚合设备的核心技术包括链路聚合、负载均衡、故障切换等&#xff0c;能够智能管理和优化利用不同网络链路&a…

websevere服务器从零搭建到上线(二)|Linux上的五种IO模型

文章目录 阻塞 blocking非阻塞 non-blockingIO复用 IO multiplexing信号驱动 signal-driven异步 asynchronous拓展知识 看过上篇文章英国基本能理解本文五张图的内容websevere服务器从零搭建到上线&#xff08;一&#xff09;&#xff5c;阻塞、非阻塞、同步、异步 本文要能够在…

HIVE统计WordCount

HIVE WORDCOUNT 目录 HIVE WORDCOUNT 一、WORDCOUNT 1.我们先创建一个新的数据库 2.创建表并插入数据 3.统计WORDCOUNT 4.UNION ALL 用法 5.WITH AS 用法 1.WORDCOUNT 1&#xff09;我们先创建一个新的数据库 create database learn3;use learn3; 2&#xff09;创建表…

知识图谱融入RAG模型:LinkedIn重塑智能客服新范式【附LeCun哈佛演讲PPT】

原文&#xff1a;Retrieval-Augmented Generation with Knowledge Graphs for Customer Service Question Answering 一、研究背景与问题 在客服领域,快速准确地匹配用户问题与历史工单,是提供优质回答的关键。传统的检索增强生成(Retrieval-Augmented Generation, RAG)方法虽…

分享5款PDF编辑软件

PDF编辑不易&#xff0c;有需要的朋友可以试试这5款专业软件&#xff0c;每一个都能直接在PDF文件上编辑&#xff0c;不同的软件对PDF可编辑的范围不同&#xff0c;大家可以按需求选用。 1.edge浏览器 Edge浏览器不仅是浏览网页的得力助手&#xff0c;还悄然成为了轻量级PDF管…

2024蓝桥杯RSA-Theorem

方法1&#xff1a;直接使用工具yafu解题 yafu的使用方法 安装&#xff1a;解压后直接使用即可&#xff0c;在文件包内&#xff0c;执行命令终端&#xff0c;输入命令行 1、如果数比较小&#xff0c;进入该文件的目录后可以直接使用: yafu-x64 factor(n) 如果是powershell&…

Embeddings原理、使用方法、优缺点、案例以及注意事项

Embeddings是一种将高维数据映射到低维空间的技术&#xff0c;常用于处理自然语言处理&#xff08;NLP&#xff09;和计算机视觉&#xff08;CV&#xff09;任务。Embeddings可以将复杂的高维数据转换为低维稠密向量&#xff0c;使得数据可以更容易地进行处理和分析。本文将介绍…

张家界(24-17)

目录 总路线酒店&#xff1a;深圳北->张家界西&#xff08;day1 07:14~13:45&#xff09;张家界西&#xff08;酒店&#xff09;->张家界森林公园东门&#xff08;day2 早上&#xff09;张家界森林公园东门->张家界西&#xff08;day2 19:48分的高铁&#xff09;张家界…

leetcode-有重复数字的全排列-98

题目要求 思路 1.同【没有重复项的全排列-97】这个题一样&#xff0c;都是递归的题&#xff0c;区别在于这个可能会包含重复的数字&#xff0c;因此&#xff0c;不能只是简单的通过两个值是否相等然后用标志位标记&#xff0c;而是新增了一个数组&#xff0c;这个数组专门用于…

树和二叉树:二叉树的基本运算算法的实现

一.前言 当前版本仅供笔者复盘 二.二叉树 2.1题目 编写一个程序&#xff0c;实现二叉树的基本运算&#xff0c;具体要求如下&#xff1a;&#xff08;指定示范实例1&#xff1a;图1。指定示范实例2&#xff1a;图2 &#xff09; 1&#xff0c;先序遍历输出该树&#xff08…

Qt QInputDialog详解

1.简介 QInputDialog是一个对话框类&#xff0c;用于从用户那里获取一个单一的值。这个值可以是字符串、数字、或者一个列表中的选项。QInputDialog提供了一个方便的方式来快速创建一个输入对话框&#xff0c;无需自己从头开始构建。 QInputDialog支持多种输入类型&#xff1…

【CTF Web】XCTF GFSJ0475 get_post Writeup(HTTP协议+GET请求+POST请求)

get_post X老师告诉小宁同学HTTP通常使用两种请求方法&#xff0c;你知道是哪两种吗&#xff1f; 解法 用 Postman 发送一个 GET 请求&#xff0c;提交一个名为a,值为1的变量。 http://61.147.171.105:65402/?a1用 Postman 发送一个 POST 请求&#xff0c;提交一个名为b,值为…

【吊打面试官系列】Java高并发篇 - 可以直接调用 Thread 类的 run ()方法么?

大家好&#xff0c;我是锋哥。今天分享关于 【可以直接调用 Thread 类的 run ()方法么&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; 可以直接调用 Thread 类的 run ()方法么&#xff1f; 当然可以。但是如果我们调用了 Thread 的 run()方法&#xff0c;它的行…

VSCode通过SSH连接虚拟机Ubuntu失败

问题说明 最近使用VSCode通过SSH连接Ubuntu&#xff0c;通过VSCode访问Ubuntu进行项目开发&#xff0c;发现连接失败 在VSCode中进行SSH配置 这些都没有问题&#xff0c;但在进行连接时候出现了问题&#xff0c;如下&#xff1a; 出现了下面这个弹窗 解决方法 发现当…