(一)哈希表
unordered_map和unsorted_set
unordered_map Key-> Value
unordered_set Key
hastable中的东西,若为基础类型,内部按值传递,否则按引用传递(内存占用为这个东西内存地址的大小)如装入hashtable的东西为struct,记录内存地址作为key
如 nodeA=new Node(1); nodeB=new Node(1) 两个不一样,因为内存地址不一样
可以认为hashtable增删改查都为常数时间的操作
内部结构无区别 ,更新Value而不更新Key
有序表和hashtable的区别:
有序表是把key按照顺序组织起来,哈希表不组织
链表解题的方法论:
笔试追求做出来,不追求空间复杂度
面试时间复杂度占第一也要找到空间最小的方法
额外技巧:
(1)额外数据结构的使用 如hashtable
(2)快慢指针
(二)题目练习
(1)实现单向链表反转 时间复杂度O(n)空间复杂度O(1)
顺便用c++的形式 写了一个链表,手有点生,犯了好几个错orz
#include <bits/stdc++.h>
using namespace std;
struct node {
int val;
node *next;
};
class Linked_list {
private:
node *head;
int length;
public:
Linked_list() {
head = nullptr;
length=0;
}
void Insert_node(int value) {
node *temp = new node();
temp->val = value;
node *p = head;
temp->next = nullptr;
if (head == nullptr) {
head = temp;
} else {
while (p->next)
p = p->next;
p->next = temp;
}
length++;
}
void Move_node(int value) {
node *p = new node();
p->next = head;
node *dummy = p;
//if (p->next)
// cout << "11111" << endl;
while (p->next != nullptr) {
if (p->next->val == value) {
node *temp = p->next;
p->next = p->next->next;
delete (temp);
length--;
} else
p = p->next;
}
head = dummy->next;
delete (dummy);
}
void Print() {
node *p = head;
while (p) {
cout << p->val << endl;
p = p->next;
}
}
int Get_length() {
return length;
}
void Reverse() {
node *p, *s, *t;
p = head;
t = nullptr;
while (p) {
s = p->next;
p->next = t;
t = p;
p = s;
}
head = t;
}
};
int main() {
Linked_list L;
L.Insert_node(3);
L.Insert_node(5);
L.Insert_node(7);
L.Insert_node(3);
L.Insert_node(9);
L.Print();
L.Reverse();
cout <<" 反转之后:" << endl;
L.Print();
L.Move_node(3);
cout << "删除节点之后:" << endl;
L.Print();
}
(2)实现双向链表的反转
(3)打印两个有序链表的公共部分 实现复杂度O(n) 额外空间复杂度O(1)
使用指针进行遍历比较,谁小谁移动,相同共同移动
(4)判断一个链表是否是回文结构
笔试遇到: 使用栈 不太考虑空间复杂度
面试遇到:快慢指针 快指针走到末尾,慢指针才走到中间 然后逆序慢指针之前的然后进行对比 记得要恢复链表
(5)给一个target ,把单链表划分成左边小中间相等右边大
笔试: 把链表复制到数组中
面试: Shead Stail Eh Et Bh Bt 然后遍历一遍链表 (tql太牛了) 一定要讨论清楚边界
(6)复制含有随机指针节点的链表
好难啊
笔试: 使用额外空间,使用hashtable,key和value都为node节点,key为老的节点,value为复制出来的新的节点
面试:生成克隆节点挂在老链表节点的下一个 然后之后的就很简单
(7)两个单链表相交的一系列问题
给定两个可能有环也可能无环的单链表,头节点为head1和head2 若两链表相交返回相交的第一个节点
判断有没有环:
(1)使用hashtable 每次先查表 可很容易得出 遍历即可
(2)快慢指针 若相遇必有环 快指针重回头节点 俩指针都一步一步走 然后相遇的地方就是第一个入环节点
判断相交:
(1)无环相交
(2)公用环,入环节点是一个
(3)公用环,入环节点不是一个