4,链表【p5】

链表

  • 4.1哈希表简介
  • 4.2有序表简介
  • 4.3链表
    • 4.3.1例1-反转单向和双向链表
    • 4.3.2例2-打印两个有序链表的公共部分
    • 4.3.3面试时链表解题的方法论
    • 4.3.4例3-判断一个链表是否为回文结构
      • 4.3.4.1快慢指针
    • 4.3.5例4-将单向链表按某值划分成左边小、中间相等、右边大的形式
    • 4.3.6例5-复制好友随机指针节点的链表
      • 4.3.6.1方法1-利用哈希表
      • 4.3.6.1方法2-不利用哈希表
    • 4.3.7例6-两个单链表相交的一系列问题
      • 4.3.7.1判断环方法1哈希表
      • 4.3.7.2判断环方法2快慢指针
        • 4.3.7.3情况1都无环
        • 4.3.7.4情况2两个链表其中一个有环,不可能相交
        • 4.3.7.5情况3两个链表都有环

4.1哈希表简介

使用哈希表,时间复杂度被认为是常数级别O(N)

哈希表在使用层面上可以理解为一种集合结构
如果只有key,没有伴随数据value,可以使用HashSet结构(C++中叫UnOrderedSet / UnSortedSet)
如果既有key,又有伴随数据value,可以使用HashMap结构(C++中叫UnOrderedMap / UnSortedMap)
有无伴随数据,是HashMap和HashSet唯一的区别,底层的实际结构的一回事
使用哈希表增(put)、删(remove)、改(put)(更新的不是key是value)、查(get)的操作,可以认为时间复杂度为O(1),但是常数时间比较大
放入哈希表的东西,如果是基础类型,内部按值传递,内存占用就是这个东西的大小
放入哈希表的东西,如果不是基础类型,内部按引用传递,内存占用是这个东西内存地址的大小

(key如果是一个长字符串,哈希表在基础类型时,值传递,所以拷贝此长字符串,所以造成空间使用很多。哈希表在不是基础类型时,引用传递,所以拷贝此长字符串地址放在哈希表内)
(nodeA=new Node(1); nodeB=new Node(1);这两个在哈希表中不是一个东西,因为nodeA有自己的地址, nodeB也有自己的地址,虽然 nodeA和 nodeB值相同,但是哈希表根据地址做的划分)
请添加图片描述
请添加图片描述

4.2有序表简介

性能相对哈希表差一点,时间复杂度O(logN)

有序表在使用层面上可以理解为一种集合结构
如果只有key,没有伴随数据value,可以使用TreeSet结构(C++中叫OrderedSet)
如果既有key,又有伴随数据value,可以使用TreeSet结构(C++中叫OrderedMap)
有无伴随数据,是TressSer和TressMap唯一的区别,底层的实际结构的一回事
有序表和哈希表的区别是,有序表把key按照顺序组织起来,而哈希表完全不组织
红黑树、AVL树、size-balance-tree和跳表等都属于有序表结构,只是底层具体实现不同
放入有序表的东西,如果是基础类型,内部按值传递,内存占用就是这个东西的大小
放入有序表的东西,如果不是基础类型,必须提供比较器(告诉编译器怎么排序),内部按引用传递,内存占用是这个东西内存地址的大小
不管是什么底层具体实现,只要是有序表,都有以下固定的基本功能和固定的时间复杂度

请添加图片描述
有序表的固定操作:

  1. void put(K key,V value): 将一个 (key,value) 记录加入到表中,或者将key的记录更新成value。
    2)V get(K key):根据给定的key,查询value并返回
  2. void remove(K key):移除key的记录。
    4)boolean containsKey(K key):问是否有关于key的记录。
    5)K firstKey():返回所有键值的排序结果中,最左(最小)的那个。
    6)K lastKey():返回所有键值的排序结果中,最右(最大)的那个。
    7)K floorKey(K key):如果表中存入过key,返回key; 否则返回所有键值的排序结果中key的前一个。
    8)K ceilingKey(K key):如果表中存入过key,返回key;否则返回所有键值的排序结果中key的后一个。

4.3链表

单链表的节点结构

Class Node<v>
{V value;Node next;
}

由以上结构的节点依次连接起来所形成的链叫单链表结构

双链表的节点结构

Class Node<v>
{V value;Node next;Node last;
}

由以上结构的节点依次连接起来所形成的链叫双链表结构

单链表和双链表结构只需要给定一个头部节点head,就可以找到剩下的所有的节点

创建一个单向链表的过程

#include <iostream>
#include <string>using namespace std;struct Student {string name;int age;string major;Student* next;
};class StudentList {
private:Student* head;public:StudentList() {head = nullptr;}void addStudent(const string& name, int age, const string& major) {// 创建新的学生节点Student* newStudent = new Student;newStudent->name = name;newStudent->age = age;newStudent->major = major;newStudent->next = nullptr;//表示链表没有下一个节点// 如果链表为空,将新节点作为头节点if (head == nullptr) {head = newStudent;}else {// 找到链表最后一个节点,将新节点插入到链表末尾Student* current = head;while (current->next) {current = current->next;}current->next = newStudent;}}void displayStudents() {Student* current = head;if (current == nullptr) {cout << "学生列表为空." << endl;return;}while (current) {cout << "姓名: " << current->name << ", 年龄: " << current->age << ", 专业: " << current->major << endl;current = current->next;}}
};int main() {// 创建学生链表对象StudentList studentList;// 添加学生信息studentList.addStudent("小明", 18, "计算机科学");studentList.addStudent("小红", 19, "数学");studentList.addStudent("小李", 20, "物理");// 显示学生信息studentList.displayStudents();return 0;
}

创建一个双向链表的过程

#include <iostream>
#include <string>using namespace std;struct Student {string name;int age;string major;Student* prev; // 添加前驱指针Student* next; // 添加后继指针
};class StudentList {
private:Student* head;public:StudentList() {head = nullptr;}void addStudent(const string& name, int age, const string& major) {// 创建新的学生节点Student* newStudent = new Student;newStudent->name = name;newStudent->age = age;newStudent->major = major;newStudent->prev = nullptr;newStudent->next = nullptr;// 如果链表为空,将新节点作为头节点if (head == nullptr) {head = newStudent;}else {// 找到链表最后一个节点,将新节点插入到链表末尾Student* current = head;while (current->next) {current = current->next;}current->next = newStudent;newStudent->prev = current;}}void displayStudents() {Student* current = head;if (current == nullptr) {cout << "学生列表为空." << endl;return;}while (current) {cout << "姓名: " << current->name << ", 年龄: " << current->age << ", 专业: " << current->major << endl;current = current->next;}}};int main() {// 创建学生链表对象StudentList studentList;// 添加学生信息studentList.addStudent("小明", 18, "计算机科学");studentList.addStudent("小红", 19, "数学");studentList.addStudent("小李", 20, "物理");// 显示学生信息studentList.displayStudents();return 0;
}

4.3.1例1-反转单向和双向链表

【题目】分别实现反转单向链表和反转双向链表的函数
【要求】如果链表长度为N,时间复杂度要求为O(N),额外空间复杂度要求为O(1)

本身链表为1节点连2节点,2节点连3节点
反转操作为3节点连2节点,2节点连1节点

如果没有换头操作,可以定义为void类型。如果换头了,那就需要带有返回值(本身链表为1节点连2节点,2节点连3节点,123。反转操作为3节点连2节点,2节点连1节点,321.所以head=f(head),head指向3节点了)

在上述单向链表代码中StudentList类中加入,调用时即可反转单向链表

void ReverseList() {if (head == nullptr || head->next == nullptr) {return;}Student* prev = nullptr;Student* current = head;Student* next = nullptr;while (current != nullptr) {// 保存下一个节点的指针next = current->next;// 反转当前节点的指针current->next = prev;// 移动指针位置prev = current;current = next;}// 更新头节点指针head = prev;}

在上述双向链表代码中StudentList类中加入,调用时即可反转单向链表

void reverseList() {if (head == nullptr || head->next == nullptr) {// 空链表或只有一个节点,无需反转return;}Student* current = head;Student* prev = nullptr;while (current) {// 保存当前节点的下一个节点Student* next = current->next;// 反转当前节点的指针current->next = prev;current->prev = next;// 更新prev和current指针prev = current;current = next;}// 更新头节点head = prev;}

4.3.2例2-打印两个有序链表的公共部分

【题目】给定两个有序链表的头指针head1和head2,打印两个链表的公共部分
【要求】如果两个链表的长度之和为N,时间复杂度要求为O(N),额外空间复杂度要求为O(1)
请添加图片描述
链表1指针先指向1,链表2指针先指向0,
对比,谁小谁移动,链表2指针先指向2,
对比,谁小谁移动,链表1指针先指向2,
对比,相等,打印2,共同移动,链表1指针先指向5,链表2指针先指向3,
对比,谁小谁移动,链表2指针先指向5,
对比,相等,打印5,共同移动,越界,停止
打印出看2,5

此方法注意要升序排列

#include <iostream>
#include <string>using namespace std;struct Student {string name;int age;string major;Student* next;
};class StudentList {
private:Student* head;public:StudentList() {head = nullptr;}void addStudent(const string& name, int age, const string& major) {// 创建新的学生节点Student* newStudent = new Student;newStudent->name = name;newStudent->age = age;newStudent->major = major;newStudent->next = nullptr;//表示链表没有下一个节点// 如果链表为空,将新节点作为头节点if (head == nullptr) {head = newStudent;}else {// 找到链表最后一个节点,将新节点插入到链表末尾Student* current = head;while (current->next) {current = current->next;}current->next = newStudent;}}void displayStudents() {Student* current = head;if (current == nullptr) {cout << "学生列表为空." << endl;return;}while (current) {cout << "姓名: " << current->name << ", 年龄: " << current->age << ", 专业: " << current->major << endl;current = current->next;}}void printCommonPart(StudentList list2) {Student* p1 = head;Student* p2 = list2.head;cout << "两个链表的公共部分: ";while (p1 && p2) {if (p1->age < p2->age) {p1 = p1->next;}else if (p1->age > p2->age) {p2 = p2->next;}else{cout << p1->age << " ";p1 = p1->next;p2 = p2->next;}}cout << endl;}
};int main() {// 创建学生链表对象StudentList studentList1;// 添加学生信息studentList1.addStudent("小明", 10, "计算机科学");studentList1.addStudent("小红", 20, "数学");studentList1.addStudent("小李", 30, "物理");StudentList studentList2;// 添加学生信息studentList2.addStudent("小红", 20, "数学");studentList2.addStudent("大明", 40, "计算机科学");studentList2.addStudent("大李", 60, "物理");// 显示学生信息studentList1.displayStudents();studentList2.displayStudents();cout << "----------------------------------" << endl;studentList1.printCommonPart(studentList2);return 0;
}

4.3.3面试时链表解题的方法论

对于笔试,不用太在乎空间复杂度,一切为了时间复杂度
对于面试,时间复杂度依然放在第一位,但是一定要找到空间最省的方法

重要技巧:
额外数据结构记录(哈希表等)
快慢指针

4.3.4例3-判断一个链表是否为回文结构

【题目】给定一个单链表的头节点head,请判断该链表是否为回文结构(正念反念一样)
【例子】1->2->1,返回true;1->2->2->1,返回true;1->20->3->20->1,返回true;1->2->3,返回false
【条件】如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1)

1->2->3->2->1
笔试:
依次把各个节点放到栈中,栈弹出的顺序是链表逆序的顺序,比对,有一步不一样即不是回文结构
请添加图片描述

#include<iostream>
#include <stack>
struct ListNode {int val;ListNode* next;ListNode(int x) : val(x), next(nullptr) {}
};bool isPalindrome(ListNode* head) {std::stack<ListNode*> stack;//创建一个空栈 stackListNode* cur = head;while (cur != nullptr) {//遍历整个链表,将每个节点指针都压栈,直到遍历到链表的尾节点stack.push(cur);cur = cur->next;}while (head != nullptr) {//再次遍历链表,同时从栈中弹出元素,依次与链表当前节点比较if (head->val != stack.top()->val) {return false;}stack.pop();head = head->next;}return true;
}
int main()
{// 创建一个示例链表: 1 -> 2 -> 3 -> 2 -> 1ListNode* node1 = new ListNode(1);ListNode* node2 = new ListNode(2);ListNode* node3 = new ListNode(3);ListNode* node4 = new ListNode(2);ListNode* node5 = new ListNode(1);node1->next = node2;node2->next = node3;node3->next = node4;node4->next = node5;// 调用判断函数bool result = isPalindrome(node1);// 输出结果if (result) {std::cout << "该链表是回文链表" << std::endl;}else {std::cout << "该链表不是回文链表" << std::endl;}// 释放内存delete node1;delete node2;delete node3;delete node4;delete node5;return 0;
}

省一点空间的做法:
把一半的右边的节点放到栈中,栈弹出的和正序进行比对,有一步不一样即不是回文结构
省了1/2的空间
怎么知道放完了一半的右边的节点,一个指针达不成要求,需要两个指针,一前一后
请添加图片描述

#include<iostream>
#include<vector>
int main()
{std::vector<int> arr= { 1,2,3,3,1,2,1 };int length = sizeof(arr) / sizeof(arr[0]);std::vector<int>::iterator Begin = arr.begin();std::vector<int>::iterator End = arr.end()-1;bool isPalindrome = true; while (Begin < End){if (*Begin != *End){isPalindrome = false;break; }Begin++;End--;}if (isPalindrome){std::cout << "true" << std::endl;}else{std::cout << "false" << std::endl;}return 0;
}

快慢指针做法:
快指针一次走两步,慢指针依次走一步,当快指针走到终点时,慢指针在中间
把一半的右边的节点放到栈中,栈弹出的和正序进行比对,有一步不一样即不是回文结构
请添加图片描述

请添加图片描述

#include<iostream>
#include <stack>
struct ListNode {int val;ListNode* next;ListNode(int x) : val(x), next(nullptr) {}
};bool isPalindrome(ListNode* head) {if (head == nullptr || head->next == nullptr) {return true;}ListNode* slow = head;ListNode* fast = head;//fast每次向后移动两个节点,直到fast达到链表的末尾或倒数第二个节点。while (fast->next != nullptr && fast->next->next != nullptr) {slow = slow->next;fast = fast->next->next;}//循环结束后,当快指针达到链表尾部或倒数第二个节点时循环结束,此时慢指针所指的节点即为链表的中间节点(针对奇数长度链表)或者右半部分链表的第一个节点(针对偶数长度链表)slow = slow->next;//将慢指针向后移动一个节点,执行右半部分链表的第一个节点std::stack<int> stack;//创建一个整型的栈//右半部分链表的节点依次入栈while (slow != nullptr) {stack.push(slow->val);slow = slow->next;}//比较ListNode* cur = head;while (!stack.empty() && cur != nullptr) {if (stack.top() != cur->val) {return false;}stack.pop();cur = cur->next;}return true;
}int main() {// 创建一个示例链表: 1 -> 2 -> 3 -> 2 -> 1ListNode* node1 = new ListNode(1);ListNode* node2 = new ListNode(2);ListNode* node3 = new ListNode(3);ListNode* node4 = new ListNode(2);ListNode* node5 = new ListNode(1);node1->next = node2;node2->next = node3;node3->next = node4;node4->next = node5;// 调用判断函数bool result = isPalindrome(node1);// 输出结果if (result) {std::cout << "该链表是回文链表" << std::endl;}else {std::cout << "该链表不是回文链表" << std::endl;}// 释放内存delete node1;delete node2;delete node3;delete node4;delete node5;return 0;
}
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:bool isPalindrome(ListNode* head) {if (head == nullptr || head->next == nullptr) {return true; // 空链表或只有一个节点的链表视为回文链表}ListNode* fast = head->next;ListNode* slow = head;// 快慢指针找到链表的中间节点while (fast != nullptr && fast->next != nullptr) {fast = fast->next->next;slow = slow->next;}// 反转后半部分链表ListNode* prev = nullptr;ListNode* curr = slow->next;while (curr != nullptr) {ListNode* nextNode = curr->next;curr->next = prev;prev = curr;curr = nextNode;}// 比较前半部分和反转后的后半部分链表ListNode* cur1 = head;ListNode* cur2 = prev;while (cur1 != nullptr && cur2 != nullptr) {if (cur1->val != cur2->val) {return false;}cur1 = cur1->next;cur2 = cur2->next;}return true;}
};

4.3.4.1快慢指针

如快指针一次走两步,慢指针依次走一步,当快指针走到终点时,慢指针在中间

需要熟练使用快慢指针
链表长度为1时,链表长度为2时,链表长度为3时,链表长度为小数时最特殊
情况1
1->2->3->2->1
奇数个时,当快指针走完,慢指针正好压中中间点,3
1->2->3->3->2->1
偶数个时,当快指针走完,慢指针正好压中中间点的前一个,3

情况2
1->2->3->2->1
奇数个时,当快指针走完,慢指针正好压中中间点,3
1->2->3->3->2->1
偶数个时,当快指针走完,慢指针正好压中中间点的后一个,3

情况3
1->2->3->2->1
奇数个时,当快指针走完,慢指针压中中间点前一个的位置,2
1->2->3->3->2->1
偶数个时,当快指针走完,慢指针压中中间点的前一个位置,2

4.3.5例4-将单向链表按某值划分成左边小、中间相等、右边大的形式

【题目】给定一个单链表的头节点head,节点的值类型是整型,再给定一个整数pivot。实现一个调整链表的函数,将链表调整为做部分都是值小于pivot的节点,中间部分都是值等于pivot的节点,右部分都是值大于pivot的节点
【进阶】在实现原问题功能的基础上增加如下要求
【要求】调整后所有小于pivot的节点之间的相对顺序和调整前一样
【要求】调整后所有等于pivot的节点之间的相对顺序和调整前一样
【要求】调整后所有小于pivot的节点之间的相对顺序和调整前一样
【要求】时间复杂度达到O(N),额外空间复杂度达到O(1)

笔试:
把单链表每一个节点放到数组中,选一个值做划分值,小于放左边,等于放中间,大于放右边,再重新串起来

面试:
数组中做不到相对顺序等,单链表可以做到
4->6->3->5->8->5->2->5->9
六个变量H头T尾,S小于,E等于,B大于
SH=NULL , ST=NULL , EH=NULL , ET=NULL , BH=NULL , BT=NULL

来到4节点,小于5
SH=4 , ST=4
来到6节点,大于5
BH=6 , BT=6
来到3节点,小于5, SH、ST不为空让ST指向3
SH=4 , ST=3
来到5节点,等于5
EH=5 , ET=5
来到8节点,大于5,BH、BT不为空让BT指向8
BH=6 , BT=8
来到5节点,等于5, ET不为空让ET指向5
EH=5 , ET=5
来到2节点,小于5, SH、ST不为空让ST指向2
SH=4 , ST=2
来到5节点,等于5, ET不为空让ET指向5
EH=5 , ET=5
来到9节点,大于5,BH、BT不为空让BT指向9
BH=6 , BT=9
请添加图片描述
连接
请添加图片描述
如果没有大于5的区域?如果没有等于5的区域?如果没有小于5的区域?
如果同时没有大于5的区域等于5的区域?
所以再三块重连时要讨论清楚连接
否则连上空指针会报错
请添加图片描述
请添加图片描述

4.3.6例5-复制好友随机指针节点的链表

【题目】一种特殊的单链表节点描述如下

class Node{int value;Node next;Node rand;Node(int val){value=val;}
}

rand指针是单链表节点结构中新增的指针,rand可能指向链表中的任意一个节点,也可能指向NULL。给定一个由Node节点类型组成的无环单链表的头节点head,请实现一个函数完成这个链表的复制,并返回复制的新链表的头节点
【要求】时间复杂度O(N),额外空间复杂度O(1)

【解析】这个链表上每个节点由next和rand两个指针,next继续链表连接,rand不一定指向哪里
请添加图片描述
目的复制出一个一样的链表

4.3.6.1方法1-利用哈希表

用额外空间时:
可以用哈希表map,key表示老节点,value表示克隆出来的新节点
遍历,(1,1’)放到map中,(2,2’)放到map中,(3,3’)放到map中
遍历哈希表或老链表均可,下述遍历老链表的方式
遍历到老链表1,查出新链表的1‘,通过老链表2和map查出新链表2’,让1‘next到2’,通过老链表3和map查出新链表3’,让1‘rand到3’
遍历到老链表2,查出新链表的2‘,通过老链表3和map查出新链表3’,让2‘next到3’,通过老链表1和map查出新链表1’,让2‘rand到1’
遍历到老链表3,查出新链表的3‘,通过老链表NULL和map知rand NULL,让3‘next到NULL,通过老链表3和map知rand NULL,让3‘rand到NULL

返回1‘即可
请添加图片描述

4.3.6.1方法2-不利用哈希表

生成克隆节点,放在老链表老节点后,先不看rand指针
请添加图片描述
通过1节点rand找到3节点,因为克隆节点放在老链表老节点后,所以可以用3节点next找到3’节点,所以1‘rand3’
请添加图片描述
如此操作得出
请添加图片描述
之后在next方向上把新老链表分离即可
请添加图片描述
请添加图片描述

4.3.7例6-两个单链表相交的一系列问题

【题目】给定两个可能有环也可能无环的单链表,头节点head1和head2.请实现一个函数,如果两个链表相交,请返回相交的第一个节点。如果不相交,返回NULL
【要求】如果两个链表长度之和为N,时间复杂度达到O(N),额外空间复杂度到大O(1)

4.3.7.1判断环方法1哈希表

请添加图片描述
遍历一个就放入容器一个,如果是环,当count发现重复就是环,不重复就不是环,发现的这个节点即是第一个入环节点

4.3.7.2判断环方法2快慢指针

请添加图片描述
慢指针一次走一个,快指针一次走两个,如果没有环,快指针会走到空就知道了没有环,如果有环就会一直走,总会碰上
快指针和慢指针碰上后,快指针回到头,快慢指针都一次走一步,它们一定会在第一个入环节点相遇
请添加图片描述

4.3.7.3情况1都无环

请添加图片描述
左边情况必定不存在,因为这样会有一个节点有两个next了,错误
遍历第一个链表,记录头head1,尾end1,长度len1
第二个链表,记录头head2,尾end2,长度len2
先判断end1和end2内存地址是不是一个,(因为无环时必定只有上图右边情况,如果相交,最后一个节点必定两个链表共有)
如果不是,必定不相交
如果是,知head1和head2的长度,先从长的走到和短的一样的剩余长度,开始一起遍历对比,一定会共同到达第一个交点
请添加图片描述
请添加图片描述
n为链表1长度减去链表2长度的值

class Solution {
public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {if(headA==nullptr||headB==nullptr){return nullptr;}ListNode*PA=headA;ListNode*PB=headB;int num=0;while(PA->next!=nullptr){num++;PA=PA->next;}while(PB->next!=nullptr){num--;PB=PB->next;}if(PA!=PB){return nullptr;}PA=num>0?headA:headB;PB=PA==headA?headB:headA;num=abs(num);while(num!=0){num--;PA=PA->next;}while(PA!=PB){PA=PA->next;PB=PB->next;}return PA;}
};

std::abs是取绝对值

4.3.7.4情况2两个链表其中一个有环,不可能相交

没有这种情况

4.3.7.5情况3两个链表都有环

有三种情况
请添加图片描述
因为已经算出了head1和head2的入环的第一个节点loop1和loop2
所以loop1=loop2的话是第二种情况
第二种情况可以算出两个链表从头到loop1的长度
和之前无环情况1相同,让长的到达节点使两个和长度相桶,之后同时开始遍历

之后开始区分情况1和情况3,从loop1开始往下走,loop2不动,在转回到loop1之前如果能碰到loop2就是情况3,碰不到就是情况1
请添加图片描述
请添加图片描述

汇总
请添加图片描述

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

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

相关文章

ORACLE和MYSQL区别

1&#xff0c;Oracle没有offet,limit&#xff0c;在mysql中我们用它们来控制显示的行数&#xff0c;最多的是分页了。oracle要分页的话&#xff0c;要换成rownum。 2&#xff0c;oracle建表时&#xff0c;没有auto_increment&#xff0c;所有要想让表的一个字段自增&#xff0c…

安装linux操作系统

安装虚拟机的步骤&#xff1a; 安装linux系统 之后开启虚拟机 之后重启&#xff0c;打开虚拟机&#xff0c;登录root账号

SpringIoc-个人学习笔记

Spring的Ioc、DI、AOP思想 Ioc Ioc思想&#xff1a;Inversion of Control&#xff0c;控制反转&#xff0c;在创建Bean的权利反转给第三方 DI DI思想&#xff1a;Dependency Injection&#xff0c;依赖注入&#xff0c;强调Bean之间的关系&#xff0c;这种关系由第三方负责去设…

如何安全变更亚马逊收款账户?

有太多的卖家想知道如何安全变更亚马逊收款账户&#xff0c;因为更改了第三方收款账户可能会导致二次视频认证或者增强视频。真的是这样吗&#xff1f; 其实不推荐亚马逊店铺正常运营之后去变更信用卡&#xff0c;收款账户等重要资料的&#xff0c;因为玩黑科技的卖家也真的多…

服务器流量

1.服务器流量分为入流量和出流量 入流量&#xff08;Inbound Traffic&#xff09;是指流向服务器的数据流量&#xff0c;也就是客户端发送到服务器的数据。这些数据可能包括请求信息、文件上传等。 出流量&#xff08;Outbound Traffic&#xff09;是指从服务器流向客户端的数…

【SCI一区】【电动车】基于ADMM双层凸优化的燃料电池混合动力汽车研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

《吐血整理》高级系列教程-吃透Fiddler抓包教程(30)-Fiddler如何抓Android7.0以上的Https包-番外篇

1.简介 通过宏哥前边几篇文章的讲解和介绍想必大家都知道android7.0以上&#xff0c;有android的机制不在信任用户证书&#xff0c;导致https协议无法抓包。除非把证书装在系统信任的证书里&#xff0c;此时手机需要root权限。但是大家都知道root手机是非常繁琐的且不安全&…

kubernetes基于helm部署gitlab-operator

kubernetes基于helm部署gitlab-operator 这篇博文介绍如何在 Kubernetes 中使用helm部署 GitLab-operator。 先决条件 已运行的 Kubernetes 集群负载均衡器&#xff0c;为ingress-nginx控制器提供EXTERNAL-IP&#xff0c;本示例使用metallb默认存储类&#xff0c;为gitlab p…

VGGNet剪枝实战:使用VGGNet训练、稀疏训练、剪枝、微调等,剪枝出只有3M的模型

摘要 本文讲解如何实现VGGNet的剪枝操作。剪枝的原理&#xff1a;在BN层网络中加入稀疏因子&#xff0c;训练使得BN层稀疏化&#xff0c;对稀疏训练的后的模型中所有BN层权重进行统计排序&#xff0c;获取指定保留BN层数量即取得排序后权重阈值thres。遍历模型中的BN层权重&am…

【NLP概念源和流】 04-过度到RNN(第 4/20 部分)

接上文 【NLP概念源和流】 03-基于计数的嵌入,GloVe(第 3/20 部分) 一、说明 词嵌入使许多NLP任务有了显著的改进。它对单词原理图的理解以及将不同长度的文本表示为固定向量的能力使其在许多复杂的NLP任务中非常受欢迎。大多数机器学习算法可以直接应用于分类和回归任务的…

[RT-Thread]基于ARTPI的文件系统认识与搭建

[写作为了记忆,个人最终输出的内容往往是遗忘后最容易捡起的内容,故以此作文] 目录 [写作为了记忆,个人最终输出的内容往往是遗忘后最容易捡起的内容,故以此作文] 前提 内容 认识 基于ARTPI的文件系统的挂载 ROMFS与LFS. &#xff08;默认自动挂载,romfs可读不可写) 搭…

Kafka系列之:记录一次Kafka Topic分区扩容,但是下游flink消费者没有自动消费新的分区的解决方法

Kafka系列之:记录一次Kafka Topic分区扩容,但是下游flink消费者没有自动消费新的分区的解决方法 一、背景二、解决方法三、实现自动发现新的分区一、背景 生产环境Kafka集群压力大,Topic读写压力大,消费的lag比较大,因此通过扩容Topic的分区,增大Topic的读写性能理论上下…

零基础C#编写上位机如何入门?

想要学习C#编写上位机&#xff0c;需要具备以下基础知识&#xff1a; C#编程语言基础.NET框架的使用WinForm窗体应用程序开发技术基本的数据结构和算法知识 为了方便理解&#xff0c;我将为您列出一些入门步骤&#xff1a; 学习C#基础语法和.NET框架&#xff0c;掌握基本编程…

opencv-33 图像平滑处理-中值滤波cv2.medianBlur()

中值滤波是一种常见的图像处理滤波技术&#xff0c;用于去除图像中的噪声。它的原理是用一个滑动窗口&#xff08;也称为卷积核&#xff09;在图像上移动&#xff0c;对窗口中的像素值进行排序&#xff0c;然后用窗口中像素值的中值来替换中心像素的值。这样&#xff0c;中值滤…

华为云CTS 使用场景

云审计服务 CTS 云审计服务&#xff08;Cloud Trace Service&#xff09;&#xff0c;帮助您监控并记录华为云账号的活动&#xff0c;包括通过控制台、API、开发者工具对云上产品和服务的访问和使用行为&#xff0c;提供对各种云资源操作记录的收集、存储和查询功能&#xff0…

【机器学习】 贝叶斯理论的变分推理

许志永 一、说明 贝叶斯原理&#xff0c;站在概率角度上似乎容易解释&#xff0c;但站在函数立场上就不那么容易了&#xff1b;然而&#xff0c;在高端数学模型中&#xff0c;必须要在函数和集合立场上有一套完整的概念&#xff0c;其迭代和运算才能有坚定的理论基础。 二、贝叶…

小研究 - 基于 MySQL 数据库的数据安全应用设计(一)

信息系统工程领域对数据安全的要求比较高&#xff0c;MySQL 数据库管理系统普遍应用于各种信息系统应用软件的开发之中&#xff0c;而角色与权限设计不仅关乎数据库中数据保密性的性能高低&#xff0c;也关系到用户使用数据库的最低要求。在对数据库的安全性进行设计时&#xf…

华为OD机试真题 Java 实现【快速人名查找】【2023 B卷 200分】,附详细解题思路

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…

促科技创新:高德数据优化篇之OceanBase最佳实践

本文作者&#xff1a; 振飞&#xff08;高德地图总裁&#xff09; 炳蔚&#xff08;高德技术服务平台负责人&#xff09; 福辰&#xff08;高德服务端架构师&#xff09; 背景 高德成立于2002年&#xff0c;是中国领先的移动数字地图、导航及实时交通信息服务提供商&#xff0c…

轻量级容器管理工具 Containerd

1. 轻量级容器管理工具 Containerd 2. Containerd的两种安装方式 3. Containerd容器镜像管理 4. Containerd数据持久化和网络管理 1. 前言 早在2016年3月&#xff0c;Docker 1.11的Docker Engine里就包含了containerd&#xff0c;而现在则是把containerd从Docker Engine里彻底…