目录
1.unordered_set
unordered_set 是 C++ 标准库中提供的一种集合容器,它是基于哈希表实现的,可以快速地插入、删除和查找元素。unordered_set 中的元素是无序的,不像 set 那样是有序的。
以下是一些关于 unordered_set 的重要特点和用法:
1.无序性:unordered_set 中的元素是无序的,插入顺序和元素值之间没有关联。
2.快速查找:由于 unordered_set 是基于哈希表实现的,查找元素的时间复杂度为 O(1),平均情况下是常数时间。
3.插入和删除:插入和删除元素的时间复杂度也是 O(1)。
4.不允许重复元素:unordered_set 中不允许存在重复的元素,每个元素在集合中只能出现一次。
5.迭代器:可以使用迭代器遍历 unordered_set 中的元素,但是迭代器不保证元素的顺序。
6.头文件:要使用 unordered_set,需要包含 <unordered_set> 头文件。
7.哈希表的count和find函数
2. lower_bound函数
auto it = lower_bound(row.begin(), row.end(), target);
lower_bound 函数来在一个容器中查找第一个不小于目标值的元素
并返回一个迭代器指向该位置。
3.两层for循环来查找 可以使用哈希表来优化
206.反转链表
解释:
/**
* 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) {}
* //solution 2这个构造函数就是尾插法直接利用
* };
*/
解法1:
//solution 1
if(head==NULL ||head->next==NULL)return head;
//没有节点和一个节点不需要反转
//因为三个指针要避免野指针,所以<2节点就会出现野指针
//所以必须要提前返回
ListNode*pA,*pB,*pC;
pA=head,pB=head->next,pC=pB->next;
//处理边界
pA->next=NULL;
while(pC){
//反转
pB->next=pA;
//指针移动
pA=pB;
pB=pC;
pC=pC->next;
}
//处理边界
pB->next=pA;
head=pB;
return head;
解法2:
//solution 2
ListNode *ans = NULL;
for (ListNode *x = head; x != NULL; x = x->next) {
ans = new ListNode(x->val,ans);//利用了其构造函数
//new 比三个指针移动快多了
}
return ans;
解法3:
//solution 3
//递归少了一个指针 将前一个节点存储在栈里
if(!head||!head->next){//递归找最后一个节点返回去
return head;
}
ListNode*newHead=reverseList(head->next);//递归下去
head->next->next=head;//递归不用担心找不到前面的节点
head->next=NULL;
return newHead;//返回时一直是最后一个节点
234.回文链表
链表:
/**
* 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) {}
* };
*/
解法1:
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(!head){
return true;
}
//先找到链表的中点 ->next 后一半的开始节点
ListNode* first=findmid(head)->next;
//翻转链表
ListNode*headB=reverseListNode(first);
//判断回文
while(headB){
if(head->val!=headB->val){
return false;
}
headB=headB->next;
head=head->next;
}
return true;
}
ListNode*findmid(ListNode*head){
//快慢指针 找中点
ListNode*fast=head;
ListNode*slow=head;
//指针要避免野指针
while(fast->next&&fast->next->next){
//避免长度不够判断进去野指针
//&&短路
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
ListNode*reverseListNode(ListNode*first){
//利用构造函数实现尾插法
ListNode*ans=NULL;
ListNode*x=first;//不修改原指针指向
while(x){
ans=new ListNode(x->val,ans);
x=x->next;
}
return ans;
//指针的指向会在函数内部被修改
}
};
解法2:
class Solution {
ListNode*firsthead;
public:
bool isPalindrome(ListNode* head) {
firsthead=head;
return recursivelyCheck(head);//递归检查
}
bool recursivelyCheck(ListNode*head){
if(head){
if(!recursivelyCheck(head->next)){
//向下递归
//判断下层的结果,如果有假就会一直传递假
return false;
}
if(firsthead->val!=head->val){
return false;
}
//相等 firsthead指针向后移动
firsthead=firsthead->next;
}
return true;
//空指针的时候返回上一个节点 就是尾节点
//return true 执行判断
//不同时空对立
}
};
24. 两两交换链表中的节点
/**
* 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:
ListNode* swapPairs(ListNode* head) {
//退出条件 没有节点和只剩一个节点 不需要交换
if(!head||!head->next){
return head;
}
//递归就是模拟情况
//考虑三条指针
ListNode*newhead=head->next;
head->next=swapPairs(newhead->next);//两个一交换
newhead->next=head;
return newhead;
}
};
ListNode*pre=new ListNode(-1,head);//创建一个头节点,统一处理
head=pre;
ListNode*cur=head->next;
while(cur&&cur->next){//退出判断条件
ListNode*tmp=cur->next;
head->next=tmp;
cur->next=tmp->next;
tmp->next=cur;
head=cur;
cur=head->next;
}
return pre->next;