系列综述:
目的:本系列是个人整理为了秋招面试
的,整理期间苛求每个知识点,平衡理解简易度与深入程度。
来源:材料主要源于左程云算法课程进行的,每个知识点的修正和深入主要参考各平台大佬的文章,其中也可能含有少量的个人实验自证。
结语:如果有帮到你的地方,就点个赞和关注一下呗,谢谢!!!
【C++】秋招&实习面经汇总篇
点此到文末惊喜↩︎
// 输入链表头节点,奇数长度返回中点,偶数长度返回上中点
Node FindNode(Node head) {
// 健壮性检查
if (head == nullptr || head->next == nullptr || head->next->next == nullptr)
return head;
// 初始化
Node slow = head->next;
Node fast = head->next->next;
while (fast->next != nullptr && fast->next->next != nullptr) {
slow = slwo->next;
fast = fast->next;
}
return slow;
}
// 输入链表头节点,奇数长度返回中点,偶数长度返回下中点
Node FindNode(Node head) {
// 健壮性检查
if (head == nullptr || head->next == nullptr || head->next->next == nullptr)
return head;
// 初始化
Node slow = head->next;
Node fast = head->next; // 初始化位置不同
while (fast->next != nullptr && fast->next->next != nullptr) {
slow = slwo->next;
fast = fast->next;
}
return slow;
}
// 定义三个匿名函数进行处理
auto 找中点
auto 反转链表
auto 比较
在这里插入代码片
unordered_map
,遍历链表存入哈希表中,再遍历一遍设置随机指针Node* copyRandomList(Node* head) {
if (head == nullptr) return nullptr;
// 复制结点并插入到结点后面
Node *cur = head;
Node *next = nullptr;
while (cur != nullptr) {
next = cur->next;
cur->next = new Node(cur->val);
cur->next->next = next;
cur = next;
}
// 复制所有结点的random关系
cur = head;
Node *cur_copy = nullptr;
while (cur != nullptr) {
next = cur->next->next; // 先记录
cur_copy = cur->next;
cur_copy->random = cur->random != nullptr ? cur->random->next : nullptr;
cur = next; // 后迭代
}
// 分离链表
Node *res = head->next;
cur = head;
while (cur != nullptr) {
// 先记录,后使用,注意每次迭代要还原和结尾情况
next = cur->next->next;
cur_copy = cur->next;
cur->next = next;
cur_copy->next = next != nullptr ? next->next : nullptr;
cur = next;
}
return res;
}
unordered_set
,一边遍历一边查set表,判断是否成环ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (headA == nullptr || headB == nullptr)
return nullptr;
ListNode *cur1 = headA;
ListNode *cur2 = headB;
// 求两个链表长度的差值
int n = 0;
while (cur1->next != nullptr) {
++n;
cur1 = cur1->next;
}
while (cur2->next != nullptr) {
--n;
cur2 = cur2->next;
}
// 如果两个链表相交,必然最后一个结点地址相同
// 否则两个链表不相交
if (cur1 != cur2) return nullptr;
cur1 = (n > 0 ? headA : headB);
cur2 = (n > 0 ? headB : headA);
n = abs(n); // 差值转正
// 长链表头先走差值步
while (n != 0) {
--n;
cur1 = cur1->next;
}
// 两个链表头一起走
while (cur1 != cur2) {
cur1 = cur1->next;
cur2 = cur2->next;
}
return cur1;
}
unordered_set
,一边遍历一边查set表,判断是否成环ListNode *detectCycle(ListNode *head) {
// 健壮性检查:注意必须都不为空
if (head == nullptr || head->next == nullptr || head->next->next == nullptr)
return nullptr;
// 先进行一次,然后就可以将判断条件设置为fast != sloww
ListNode *fast = head->next->next;
ListNode *slow = head->next;
// 快指针走两步,慢指针走一步
while (fast != slow) {
if (fast->next == nullptr || fast->next->next == nullptr)
return nullptr;
slow = slow->next;
fast = fast->next->next;
}
// 然后快指针指向头,两个指针同步每次走一步
fast = head;
while (fast != slow) {
slow = slow->next;
fast = fast->next;
}
return slow;
}
点此跳转到首行↩︎