剑指Offer 30-35

162 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

一、题目内容

image.png

二、解题方法

  • 根据栈的特点,我们需要设计一个辅助栈,与元素同步插入与删除,用于存储每个元素对应的最小值。

  • push方法:首先将元素要入元素栈中,然后将元素值与辅助栈栈顶元素比较,如果元素值较小,就将当前元素压入辅助栈中,否则就将辅助栈栈顶元素要入栈中。

  • pop方法:弹出元素栈和辅助栈栈顶元素

  • top方法:获取元素栈栈顶元素值

  • min方法:获取辅助栈栈顶元素值

  • 时间复杂度:O(1) O(1)。因为栈的插入、删除与读取操作都是 O(1)O(1),我们定义的每个操作最多调用栈操作两次。

  • 空间复杂度:O(n)O(n),其中nn为总操作数。最坏情况下,我们会连续插入n n 个元素,此时两个栈占用的空间为 O(n)O(n)

  • 题解代码如下:

var MinStack = function() {
    this.stack = [];
    this.min_stack = [];
};

MinStack.prototype.push = function(x) {
    this.stack.push(x);
    if(this.min_stack.length!=0){
        if(this.min()>x){
            this.min_stack.push(x);
        }else{
            this.min_stack.push(this.min());
        }
    }else{
        this.min_stack.push(x);
    }
};


MinStack.prototype.pop = function() {
    this.stack.pop();
    this.min_stack.pop();
};


MinStack.prototype.top = function() {
    return this.stack[this.stack.length-1];
};


MinStack.prototype.min = function() {
    return this.min_stack[this.min_stack.length-1];
};

一、题目内容

image.png

二、解题方法

  • 复制原始链表A→ B → C的节点,将每个节点复制,作为当前节点的猴急节点,复制后的结果为 A → A' → B →B' → C → C'

  • 然后设置每个后继节点的random指针,是其与原始节点的random指向一样

  • 将原始节点和后继节点从原始链表中拆分出来,返回后继节点链表的表头

  • 时间复杂度:O(n)O(n),其中 nn是链表的长度。只需要遍历该链表三次:复制节点遍历一次,设置random指向遍历一次,拆分链表遍历一次。

  • 空间复杂度:O(1)O(1)。注意返回值不计入空间复杂度。

  • 题解代码如下:

/**
 * // Definition for a Node.
 * function Node(val, next, random) {
 *    this.val = val;
 *    this.next = next;
 *    this.random = random;
 * };
 */

var copyRandomList = function(head) {
    if (head === null) {
        return null;
    }
    // 1.复制结点
    let cur = head;
    while(cur!=null){
        copy_node = new Node(cur.val);
        copy_node.next = cur.next;
        cur.next = copy_node;
        cur = cur.next.next;
    }
    
    // 2.设置random
    cur = head;
    while(cur!=null){
        if(cur.random!=null){
            cur.next.random = cur.random.next;
        }
        cur = cur.next.next;
    }
    
    // 3.拆分列表
    const headNew = head.next;
    for (let node = head; node !== null; node = node.next) {
        const nodeNew = node.next;
        node.next = node.next.next;
        nodeNew.next = (nodeNew.next !== null) ? nodeNew.next.next : null;
    }

    return headNew;
};