剑指Offer
用两个栈实现队列
链接:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/
题目描述:
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
示例:
输入:
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[[],[],[5],[2],[],[]]
输出:[null,-1,null,null,5,2]
完整代码:
class CQueue {
public:
/*
定义两个栈,分别为输入栈、输出栈。
当append操作时,向输入栈加入元素
当delete操作时,判断输出栈是否为空
若输出栈不为空,直接删除栈顶元素
若输出栈为空,输入栈不为空,将输入栈全部元素按顺序压入输出栈内,删除栈顶元素
若两个栈都为空,return -1
*/
CQueue() {
}
void appendTail(int value) {
input.push(value);
}
int deleteHead() {
if(input.empty() && output.empty()) return -1;
int dv;
if(!output.empty())
{
dv = output.top();
output.pop();
}
else
{
while(!input.empty())
{
output.push(input.top());
input.pop();
}
dv = output.top();
output.pop();
}
return dv;
}
stack<int> input;
stack<int> output;
};
/**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/
包含min函数的栈
链接:https://leetcode-cn.com/problems/bao-han-minhan-shu-de-zhan-lcof/
题目描述:
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.min(); --> 返回 -2.
完整代码:
class MinStack {
public:
/*
定义一个普通栈和一个维护较小值的栈。
minsck:较小值的栈,该栈的栈顶为最小值,栈下面的元素均递增顺序
而且越下面的元素在普通栈中也越下面,这样保证了pop()操作时候可能
需要更新最小值,当需要更新时,直接minsck.pop()即可。
做法:当push操作时
如果minsck为空,代表当前没有最小值,直接将元素value压入minsck中
如果minsck不为空,代表当前栈顶为最小值,如果元素value小于top(),则加入minsck,否则不加入。
*/
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
if(minsck.empty()) minsck.push(x);
else if(minsck.top() >= x) minsck.push(x);
tsck.push(x);
}
void pop() {
if(tsck.empty()) return ;
if(minsck.top() == tsck.top())
{
minsck.pop();
}
tsck.pop();
}
int top() {
if(tsck.empty()) return -1;
return tsck.top();
}
int min() {
if(minsck.empty()) return -1;
return minsck.top();
}
stack<int> minsck;
stack<int> tsck;
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(x);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->min();
*/
另一种解法:以空间换时间,当数据量大的时候使用的空间也增大,额外使用了很大空间维护最小值
class MinStack {
public:
/** initialize your data structure here. */
int Min=INT_MAX;
stack<int> st;
MinStack() {
}
//每次将最小值插入到新增的元素下面,为了pop操作时,取得栈顶为最小值
void push(int x) {
st.push(Min);//加入上一个最小值
if(x<Min) Min=x;//更新最小值
st.push(x);//加入该数值
}
void pop() {
st.pop();//pop掉该数值
Min=st.top();//得到去掉该值后的最小值
st.pop();//将该最小值也pop掉
}
int top() {
return st.top();//返回栈顶即可
}
int min() {
return Min;
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(x);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->min();
*/
从尾到头打印链表
链接:https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/
题目描述:
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
完整代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
if(head == nullptr) return {};
vector<int> ans;
ListNode* p = head;
while(p)
{
ans.push_back(p->val);
p = p->next;
}
reverse(ans.begin(),ans.end());
return ans;
}
};
反转链表
链接:https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/
题目描述:
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
在输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
完整代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == nullptr) return nullptr;
ListNode* pre = nullptr , *cur = head;
while(cur)
{
ListNode* t = cur->next;
cur->next = pre;
pre = cur;
cur = t;
}
return pre;
}
};
复杂链表的复制
链接:https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/
题目描述:
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
完整代码:
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
/*
利用哈希表: old head --> new head
*/
Node* copyRandomList(Node* head) {
if(head == nullptr) return nullptr;
unordered_map<Node*,Node*> res;
Node* p = head;
while(p)
{
Node* t = new Node(p->val);
res[p] = t;
p = p->next;
}
p = head;
while(p)
{
res[p]->next = res[p->next];
res[p]->random = res[p->random];
p = p->next;
}
return res[head];
}
};