每日一题之数据结构-数组篇

栈 Stack

栈是一种具有特定行为的线性数据结构,遵循 后进先出(LIFO) 的原则。也就是说,最后放入栈的元素最先被取出。
栈的特点是 只能在栈顶进行插入(压栈)和删除(弹栈) 操作,其他位置的元素无法直接访问。类比现实生活中的栈,可以将其看作是一摞盘子,最后放入的盘子最先被取出。

括号匹配

  • 一个字符串内部可能包含 { } ( ) [ ] 三种括号,判断该字符串是否是括号匹配的。如 ({})[{()}] 就是匹配的, {a(b{a(b}c) 就是不匹配的。

  • 思路:

    • 遇到做括号 { [ ( 则压入栈
    • 遇到右括号 } ] ) 则判断栈顶, 相同的则出栈
    • 最后判断栈的长度是否为0
/**
 * @param {string} s
 * @return {boolean}
 */
function isValid(s) {
  const stack = [];
  const bracketMap = new Map([
    ["}", "{"],
    ["]", "["],
    [")", "("],
  ]);
  if (s.length % 2 !== 0) {
    return false;
  }

  for (let char of s) {
    // 判断Map中是否存在 {, (, [, 首先遇到开括号肯定不存在, 所以走else, 将开括号压入栈, 遇到闭括号进入if判断
    if (bracketMap.has(char)) {
      const top = stack.pop();
      if (top !== bracketMap.get(char)) {
        return false;
      }
    } else {
      stack.push(char);
    }
  }
  return stack.length === 0;
}

最小栈

  • 思路:
    • 我们需要维护一个辅助栈作为取最小栈的数组 min_stack
    • 当一个元素要入栈, 我们取辅助栈的栈顶存储的最小值和需要入栈的元素做对比,取出最小值, 将最小值压入辅助栈, 这样辅助栈栈顶绝对是最小值
    • 当一个元素要出栈, 除了需要对栈操作还需要对辅助栈弹出最小值
var MinStack = function () {
  this.x_stack = [];
  this.min_stack = [Infinity];
};

MinStack.prototype.push = function (x) {
  this.x_stack.push(x);
  this.min_stack.push(Math.min(this.min_stack[this.min_stack.length - 1], x));
};
MinStack.prototype.pop = function () {
  this.x_stack.pop();
  this.min_stack.pop();
};
MinStack.prototype.top = function () {
  return this.x_stack[this.x_stack.length - 1];
};
MinStack.prototype.getMin = function () {
  return this.min_stack[this.min_stack.length - 1];
};

删除有序数组中的重复项

  • 思路:
    • 使用双指针
    • 让快指针走在最前面, 如果快指针的前一位和后一位不相等, 则慢指针当前的位置等于快指针位置的值, 同时慢指针往前移一位
/**
 * 删除排序数组中的重复项
 *  双指针
 * @param {number[]} nums
 * @returns {number}
 * @description 给定一个数组[1, 2, 3, 4, 4, 5], 剔除重复的, 返回数组的长度, 数组是升序
 */
var removeDuplicates = function (nums) {
  const n = nums.length;
  if (n === 0) {
    return 0;
  }
  let fast = 1, slow = 1;
  while(fast < n) {
    // 判断前一位和后一位不相等
    if (nums[fast] !== nums[fast - 1]) {
      nums[slow] = nums[fast];
      ++slow;
    }
    ++fast;
  }
  return slow;
};
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值