0
点赞
收藏
分享

微信扫一扫

剑指Offer

柠檬的那个酸_2333 2022-04-16 阅读 59

剑指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];
    }
};
举报

相关推荐

0 条评论