c++面试笔试总结
第一题:反转链表
描述
给定一个单链表的头结点pHead,长度为n,反转该链表后,返回新链表的表头。
数据范围: n\leq1000n≤1000
要求:空间复杂度 O(1)O(1) ,时间复杂度 O(n)O(n) 。
如当输入链表{1,2,3}时,
经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
以上转换过程如下图所示:
输入实例:输入{1,2,3} 输出{3,2,1};实例2: 输入{} 输出{}
方法一:利用两个链表,三个指针,分别为nex指针(用于保存原链表的表头指针),pre指针(用于保存新链表的表头指针Phead),cur指针(用于取下原链表节点并插入新链表中)
链表的结构定义为:
//结构体的定义
struct ListNode {
int val;//值
struct ListNode *next;//下一个节点
ListNode(int x) :
val(x), next(NULL) {
}
};
//倒转链表
class Solution{
public:
ListNode* ReverseList(ListNode* pHead){
ListNode* cur = pHead;
ListNode* pre = nullptr;
ListNode* nex = nullptr;
while(cur){
//当cur为空的时候表示原链表已经摘取完,退出循环并返回新链表的表头
nex = cur->next;
cur->next = pre;
pre = cur;
cur = nex;
}
return pre;
}//ListNode
}
步骤如下:
方法二:利用栈解决,因为栈是一个先进先出的结构,将链表中的元素值取出,压入栈中(push),然后取栈顶指针,建立新的链表,然后pop()栈顶指针,直到栈空结束。时间复杂度和空间复杂度都较高。
方法三:利用vector容器保存节点指针。然后先令头指针指向最后一个结点,从倒数第二个元素开始反向遍历vector,后插法建立新的链表。
class Solution {
public:
ListNode*ReverseList(ListNode* pHead){
if(pHead ==NULL||pHead->next == NULL)return pHead;
vector<ListNode*>V;
while(pHead){
V.push_back(pHead);//指针依次将元素压入放入vector容器的后面
pHead = pHead->next;
}
ListNode* Head = V[V.size()-1];//先将新链表的头指针指向Vector容器的尾
ListNode* p = Head;//然后一次从倒数第二个元素开始使用尾插法建立新链表
for (int i = V.size()-1;i>=0;i--){
p->next = V[i];//修改当前指针的后续指向
p = p->next;//移动链表的指针
}
//最后出来以后将p->next进行后续的赋空
p->next = NULL;
return Head;
}
};
设计LRU 缓存结构
描述
设计LRU(最近最少使用)缓存结