系列综述:
目的:本系列是个人整理为了秋招面试
的,整理期间苛求每个知识点,平衡理解简易度与深入程度。
来源:材料主要源于左程云算法课程进行的,每个知识点的修正和深入主要参考各平台大佬的文章,其中也可能含有少量的个人实验自证。
结语:如果有帮到你的地方,就点个赞和关注一下呗,谢谢!!!
【C++】秋招&实习面经汇总篇
点此到文末惊喜↩︎
// 单链表数据结构
struct LinkNode {
int val;
struct LinkNode *next;
LinkNode(int v): val(v), next(nullptr){}
};
// 反转单链表
LinkNode *ReverseLinkList(LinkNode *head) {
LinkNode *prev = nullptr;
LinkNode *next = nullptr;
while (head != nullptr) { // head充当cur指针,表示每个操作的结点
next = head->next; // 记录值
head->next = prev;
prev = head; // 两个指针的迭代
head = next;
}
return prev;
}
双链表
作为底层实现栈和队列
struct LinkNode {
int val;
struct LinkNode *prev;
struct LinkNode *next;
LinkNode(int v): val(v), prev(nullptr), next(nullptr){}
};
// 反转双向链表
LinkNode *ReverseLinkList(LinkNode *head) {
LinkNode *prev = nullptr;
LinkNode *next = nullptr;
while (head != nullptr) { // head充当cur指针,表示每个操作的结点
next = head->next; // 记录值
head->next = prev; // key:当前双链表结点两个指针反转
head->prev = next;
prev = head; // 两个指针的迭代
head = next;
}
return prev;
}
// 删除指定结点
ListNode *DeleteTarget(ListNode *head, int target) {
ListNode *vhead = new ListNode(-1);
vhead->next = head;
ListNode *prev = vhead;
ListNode *cur = head;
while (cur != nullptr) {
if (cur->val == target) {
ListNode *p = cur;
cur = cur->next;
delete p; // 释放结点,jvm会自动释放
prev->next = cur;
} else {
prev = cur;
cur = cur->next;
}
}
return vhead->next;
}
设计一个模板双链表,可以进行头部和尾部的增删,以及改查操作,并进行优化
双链表实现栈和队列
数组实现栈和队列
以O(1)时间获取当前栈的最小值
class MinStack {
public:
/** initialize your data structure here. */
MinStack() {
min_st.push(INT_MAX);
}
void push(int x) {
cur_st.push(x);
int p = min_st.top();
// 最小栈的栈顶一直记录栈内的最小值
if (x <= p) {
min_st.push(x);
} else {
min_st.push(p);
}
}
void pop() {
cur_st.pop();
min_st.pop();
}
int top() {
return cur_st.top();
}
int getMin() {
return min_st.top();
}
private:
// 使用两个栈记录,一个记录当前栈,另一个栈顶一直为栈内最小元素
stack<int> cur_st;
stack<int> min_st;
};
栈
实现队列
class MyQueue {
public:
MyQueue() {
}
// 弹出栈为空则压入栈全部倒进弹出栈中
void PushToPop(){
if (pop_st.empty()) {
while (!push_st.empty()) {
pop_st.push(push_st.top());
push_st.pop();
}
}
}
// 压入一个,则尝试倒栈
void push(int x) {
push_st.push(x);
PushToPop();
}
// 先倒栈,在尝试弹出
int pop() {
PushToPop();
int p = pop_st.top();
pop_st.pop();
return p;
}
int peek() {
PushToPop();
return pop_st.top();
}
bool empty() {
return pop_st.empty() && push_st.empty();
}
private:
stack<int> push_st;
stack<int> pop_st;
};
队列
实现栈
class MyStack {
public:
queue<int> que;
/** Initialize your data structure here. */
MyStack() { }
/** Push element x onto stack. */
void push(int x) {
que.push(x);
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int size = que.size();
size--;
while (size--) { // 将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部
que.push(que.front());
que.pop();
}
int result = que.front(); // 此时弹出的元素顺序就是栈的顺序了
que.pop();
return result;
}
// 队列的末尾元素即为栈顶元素
int top() {
return que.back();
}
/** Returns whether the stack is empty. */
bool empty() {
return que.empty();
}
};
全局或者引用
,其中的可变参数作为参数int process(vector<int> &vec, int L, int R) {
if (L == R) return vec[L];
int mid = L + ((R-L)>>1);
int left_max = process(vec, L, mid);
int right_max = process(vec, mid+1, R);
return max(left_max, right_max);
}
点此跳转到首行↩︎