leetcode - 必背基础题(JS版)

本文详细解析了LeetCode中涉及JavaScript的基础题目,涵盖字符串操作、二进制数学、数组处理、二分查找、快慢指针、滑动窗口、矩阵问题以及栈和队列的应用。通过实例讲解,帮助开发者提升算法能力和编程技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、leetcode - 字符串
二、leetcode - 二进制、数学类
三、leetcode - 数组
四、leetcode - 二分查找
五、leetcode - 快慢指针
六、leetcode - 滑动窗口
七、leetcode - 矩阵
八、leetcode - 栈和队列

一、leetcode - 字符串

344. 反转字符串
/**
 * @param {character[]} s [ "h", "e", "l", "l", "o" ]
 * @return {void} [ "o", "l", "l", "e", "h" ] Do not return anything, modify s in-place instead.
 */
var reverseString = function (s) {
  let l = 0;
  let r = s.length - 1;
  while (l <= r) {
    [s[l], s[r]] = [s[r], s[l]];
    l++;
    r--;
  }
  return s;
};
9. 回文数
/**
 * @param {number} x 121
 * @return {boolean} true
 */
var isPalindrome = function (x) {
  let arr = x.toString();
  let len = arr.length;
  for (let i = 0; i < len / 2; i++) {
    console.info(arr[i] + "  " + arr[len - 1 - i]);
    if (arr[i] !== arr[len - 1 - i]) {
      return false;
    }
  }
  return true;
  //   return x.toString() === x.toString().split("").reverse().join("");
};
125. 验证回文串
/**
 * @param {string} s "A man, a plan, a canal: Panama"
 * @return {boolean} true
 */
var isPalindrome = function (s) {
  s = s.toLowerCase().replace(/[^a-z0-9]/g, "");
  let l = 0;
  let r = s.length - 1;
  while (l <= r) {
    if (s[l] !== s[r]) return false;
    l++;
    r--;
  }
  return true;
};
242. 有效的字母异位词

st 中每个字符出现的次数都相同,则称 st 互为字母异位词。

/**
 * @param {string} s "anagram"
 * @param {string} t "nagaram"
 * @return {boolean} true
 */
var isAnagram = function (s, t) {
  let sLen = s.length;
  let tLen = t.length;
  if (sLen !== tLen) return false;
  let count = {};
  for (let i = 0; i < sLen; i++) {
    count[s[i]] ? count[s[i]]++ : (count[s[i]] = 1);
    count[t[i]] ? count[t[i]]-- : (count[t[i]] = -1);
  }
  return Object.values(count).every((item) => item === 0);
};

二、leetcode - 二进制、数学类

191. 位 1 的个数
/**
 * @param {number} n - a positive integer 00000000000000000000000000001011
 * @return {number} 3 输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。
 */
var hammingWeight = function (n) {
  let res = 0;
  while (n) {
    n = (n - 1) & n;
    res++;
  }
  return res;
};
326. 3 的幂
/**
 * @param {number} n 27
 * @return {boolean} true
 */
var isPowerOfThree = function (n) {
  while (n >= 3) {
    n = n / 3;
  }
  return n === 1;
};
136. 只出现一次的数字
相同值异或运算为0,与0进行异或运算为原值
res  运算过程
0    2^2=0
1    0^1=1
/**
 * @param {number[]} nums [2,2,1]
 * @return {number} 1
 */
var singleNumber = function (nums) {
  let res = nums[0];
  for (let i = 1; i < nums.length; i++) {
    res ^= nums[i];
  }
  return res;
};
172. 阶乘后的零
/**
 * @param {number} n n = 5
 * @return {number} 1 5! = 120 ,有一个尾随 0
 */
var trailingZeroes = function (n) {
  let res = 0;
  while (n > 1) {
    n = (n / 5) | 0;
    res += n;
  }
  return res;
};
7. 整数反转
res=-3   x=-12
res=-32  x=-1
res=-321 x=0

res=0  x=12
res=2  x=1
res=21 x=0
/**
 * @param {number} x -123/120
 * @return {number} -321/21
 */
var reverse = function (x) {
  let res = 0;
  let min = Math.pow(-2, 31);
  let max = Math.pow(2, 31) - 1;
  while (x) {
    res = res * 10 + (x % 10); // x % 10: 取10进制的个位数字
    if (res > max || res < min) return 0;
    x = (x / 10) | 0; // 取10进制个位以上的数字
  }
  return res;
};
171. Excel 表列序号
/**
 * @param {string} columnTitle "AB"
 * @return {number} 28
 */
var titleToNumber = function (columnTitle) {
  let ans = 0;
  for (let item of columnTitle) {
    ans = ans * 26 + (item.charCodeAt() - "A".charCodeAt() + 1);
  }
  return ans;
};

三、leetcode - 数组

217. 存在重复元素
/**
 * @param {number[]} nums [1,2,3,1]
 * @return {boolean} true
 */
var containsDuplicate = function (nums) {
  let map = {};
  for (let item of nums) {
    if (map[item]) return true;
    map[item] = true;
  }
  return false;
};
349. 两个数组的交集

输出结果中的每个元素一定是唯一的

map 双循环

/**
 * @param {number[]} nums1 [1,2,2,1]
 * @param {number[]} nums2 [2,2]
 * @return {number[]} [2]
 */
var intersection = function (nums1, nums2) {
  let map = {};
  let res = [];
  for (let item of nums1) {
    map[item] = true;
  }
  for (let item of nums2) {
    if (map[item]) {
      res.push(item);
      map[item] = false;
    }
  }
  return res;
};
1. 两数之和 输入无序数组

map

/**
 * @param {number[]} nums [2,7,11,15]
 * @param {number} target 9
 * @return {number[]} [0,1]
 */
var twoSum = function (nums, target) {
  let map = {};
  for (let i = 0; i < nums.length; i++) {
    if (map[nums[i]] !== undefined) {
      return [map[nums[i]], i];
    }
    map[target - nums[i]] = i;
  }
};
88. 合并两个有序数组

双数组双指针

/**
 * @param {number[]} nums1 [1,2,3,0,0,0]
 * @param {number} m 3
 * @param {number[]} nums2 [2,5,6]
 * @param {number} n 3
 * @return {void} [1,2,2,3,5,6] Do not return anything, modify nums1 in-place instead.
 */
var merge = function (nums1, m, nums2, n) {
  let len = m + n - 1;
  let mLen = m - 1;
  let nLen = n - 1;
  while (mLen >= 0 && nLen >= 0) {
    if (nums1[mLen] > nums2[nLen]) {
      nums1[len] = nums1[mLen];
      mLen--;
    } else {
      nums1[len] = nums2[nLen];
      nLen--;
    }
    len--;
  }
  while (nLen >= 0) {
    nums1[len] = nums2[nLen];
    nLen--;
    len--;
  }
};
14. 最长公共前缀

使用 reduce 两两比较。

/**
 * @param {string[]} strs ["flower","flow","flight"]
 * @return {string} "fl"
 */
var longestCommonPrefix = function (strs) {
  let len = strs.length;
  if (len === 0) return "";
  if (len === 1) return strs[0];
  return strs.reduce(function (a, b) {
    let res = "";
    for (let i = 0; i < a.length; i++) {
      if (a[i] === b[i]) {
        res += a[i];
      } else {
        break;
      }
    }
    return res;
  });
};

四、leetcode - 二分查找

Math.floor(left + (right - left) / 2)

704. 二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

/**
 * @param {number[]} nums [-1,0,3,5,9,12]
 * @param {number} target 9
 * @return {number} 4
 */
var search = function (nums, target) {
  let left = 0;
  let right = nums.length - 1;
  let res = -1;
  while (left <= right) {
    let mid = (right + left) >> 1;
    if (nums[mid] === target) {
      res = mid;
      break;
    }
    if (nums[mid] > target) right = mid - 1;
    if (nums[mid] < target) left = mid + 1;
  }
  return res;
};
875. 爱吃香蕉的珂珂

珂珂喜欢吃香蕉。这里有 N 堆香蕉,第 i 堆中有 piles[i] 根香蕉。警卫已经离开了,将在 H 小时后回来。

珂珂可以决定她吃香蕉的速度 K (单位:根/小时)。每个小时,她将会选择一堆香蕉,从中吃掉 K 根。如果这堆香蕉少于 K 根,她将吃掉这堆的所有香蕉,然后这一小时内不会再吃更多的香蕉。

珂珂喜欢慢慢吃,但仍然想在警卫回来前吃掉所有的香蕉。

返回她可以在 H 小时内吃掉所有香蕉的最小速度 K(K 为整数)。

/**
 * @param {number[]} piles [3,6,7,11]
 * @param {number} h 8
 * @return {number} 4
 */
var minEatingSpeed = function (piles, h) {
  let left = 1;
  let right = Math.max(...piles);
  while (left <= right) {
    const mid = Math.floor(left + (right - left) / 2);
    if (canFinish(piles, mid, h)) {
      right = mid - 1;
    } else {
      left = mid + 1;
    }
  }
  return left;
};
function canFinish(piles, speed, h) {
  let time = 0;
  for (let n of piles) {
    time += ((n / speed) | 0) + (n % speed > 0 ? 1 : 0);
  }
  return time <= h;
}
35. 搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。

/**
 * @param {number[]} nums [1,3,5,6]
 * @param {number} target 5
 * @return {number} 2
 */
var searchInsert = function (nums, target) {
  let left = 0;
  let right = nums.length - 1;
  let index = nums.length;
  while (left <= right) {
    let mid = (left + right) >> 1;
    if (target > nums[mid]) {
      left = mid + 1;
    } else {
      index = mid;
      right = mid - 1;
    }
  }
  return index;
};

五、leetcode - 快慢指针

26. 删除有序数组中的重复项
              修改前          修改后         修改后的slow
slow=0 fast=0 [ 1, 1, 1, 2 ] [ 1, 1, 1, 2 ] slow=0
slow=0 fast=1 [ 1, 1, 1, 2 ] [ 1, 1, 1, 2 ] slow=0
slow=0 fast=2 [ 1, 1, 1, 2 ] [ 1, 1, 1, 2 ] slow=0
slow=0 fast=3 [ 1, 1, 1, 2 ] [ 1, 2, 1, 2 ] slow=1
/**
 * @param {number[]} nums [1,1,2]
 * @return {number} 2, nums = [1,2]
 */
var removeDuplicates = function (nums) {
  let slow = 0; // 包括慢指针在内的之前元素都是不重复的
  let fast = 0;
  while (fast < nums.length) {
    if (nums[fast] !== nums[slow]) {
      nums[slow + 1] = nums[fast];
      slow++;
    }
    fast++;
  }
  return slow + 1; // slow是从0开始的下标,所以长度需要+1
};
27. 移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

              修改前          修改后         修改后的slow
slow=0 fast=0 [ 3, 2, 2, 3 ] [ 3, 2, 2, 3 ] slow=0
slow=0 fast=1 [ 3, 2, 2, 3 ] [ 2, 2, 2, 3 ] slow=1
slow=1 fast=2 [ 2, 2, 2, 3 ] [ 2, 2, 2, 3 ] slow=2
slow=2 fast=3 [ 2, 2, 2, 3 ] [ 2, 2, 2, 3 ] slow=2
/**
 * @param {number[]} nums [3,2,2,3]
 * @param {number} val 3
 * @return {number} 2, nums = [2,2]
 * 函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
 */
var removeElement = function (nums, val) {
  let slow = 0; // 慢指针之前的元素都是移除目标元素的
  let fast = 0;
  while (fast < nums.length) {
    if (nums[fast] !== val) {
      nums[slow] = nums[fast];
      slow++;
    }
    fast++;
  }
  return slow;
};
283. 移动零

快慢指针

              修改前              修改后             修改后的slow
slow=0 fast=0 [ 0, 1, 0, 3, 12 ] [ 0, 1, 0, 3, 12 ] slow=0
slow=0 fast=1 [ 0, 1, 0, 3, 12 ] [ 1, 0, 0, 3, 12 ] slow=1
slow=1 fast=2 [ 1, 0, 0, 3, 12 ] [ 1, 0, 0, 3, 12 ] slow=1
slow=1 fast=3 [ 1, 0, 0, 3, 12 ] [ 1, 3, 0, 0, 12 ] slow=2
slow=2 fast=4 [ 1, 3, 0, 0, 12 ] [ 1, 3, 12, 0, 0 ] slow=3
/**
 * @param {number[]} nums [0,1,0,3,12]
 * @return {void} [1,3,12,0,0] Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function (nums) {
  let slow = 0; // 慢指针之前的元素都是不含0元素的
  let fast = 0;
  while (fast < nums.length) {
    if (nums[fast] !== 0) {
      let temp = nums[slow];
      nums[slow] = nums[fast];
      nums[fast] = temp;
      slow++;
    }
    fast++;
  }
};

六、leetcode - 滑动窗口

3. 无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

{ a: 1 }             l=0 r=1 res=1
{ a: 1, b: 1 }       l=0 r=2 res=2
{ a: 1, b: 1, c: 1 } l=0 r=3 res=3
{ a: 1, b: 1, c: 1 } l=1 r=4 res=3
{ a: 1, b: 1, c: 1 } l=2 r=5 res=3 `
{ a: 1, b: 1, c: 1 } l=3 r=6 res=3
{ a: 0, b: 1, c: 1 } l=5 r=7 res=3
{ a: 0, b: 1, c: 0 } l=7 r=8 res=3
/**
 * @param {string} s "abcabcbb"
 * @return {number} 3 因为无重复字符的最长子串是 "abc"
 */
var lengthOfLongestSubstring = function (s) {
  let l = 0;
  let r = 0;
  let res = 0;
  let map = {}; // 维护一个无重复字符的窗口
  while (r < s.length) {
    let temp = s[r];
    r++; // 窗口内容无重复之前,始终扩张窗口
    map[temp] = (map[temp] || 0) + 1; // 增加窗口内容
    while (map[temp] > 1) {
      // 窗口内容有重复,则缩小窗口
      map[s[l]]--; // 缩小窗口内容
      l++; // 缩小窗口
    }
    res = Math.max(res, r - l); // 更新最长子串长度
  }
  return res;
};
209. 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

2 l=0 r=1 res=Infinity
5 l=0 r=2 res=Infinity
6 l=0 r=3 res=Infinity
6 l=1 r=4 res=4
6 l=3 r=5 res=3
3 l=5 r=6 res=2
/**
 * @param {number} target 7
 * @param {number[]} nums [2,3,1,2,4,3]
 * @return {number} 2 子数组 [4,3] 是该条件下的长度最小的子数组
 */
var minSubArrayLen = function (target, nums) {
  let l = 0;
  let r = 0;
  let res = Infinity;
  let sum = 0; // 维护一个子数组的和大于等于target
  while (r < nums.length) {
    let cur = nums[r];
    r++; // 子数组的和大于等于target之前,始终扩张窗口
    sum += cur;
    while (sum >= target) {
      // 子数组的和大于等于target,则缩小窗口
      res = Math.min(res, r - l); // 更新长度最小的子数组
      sum -= nums[l];
      l++; // 缩小窗口
    }
  }
  return res === Infinity ? 0 : res;
};
904. 水果成篮
{ '1': 1 }                 l=0 r=1 res=1
{ '1': 1, '2': 1 }         l=0 r=2 res=2
{ '1': 0, '2': 1, '3': 1 } l=1 r=3 res=2
{ '1': 0, '2': 2, '3': 1 } l=1 r=4 res=3
{ '1': 0, '2': 3, '3': 1 } l=1 r=5 res=4
/**
 * @param {number[]} fruits [1,2,3,2,2]
 * @return {number} 4
 * 我们可以收集 [2,3,2,2] 如果我们从第一棵树开始,我们将只能收集到 [1, 2]
 */
var totalFruit = function (tree) {
  let l = 0;
  let r = 0;
  let map = {}; // 维护一个连续水果种类为2的窗口
  let count = 0; // 能携带水果的类型,最多2种
  let res = 0; // 能收集的水果树的最大总量
  while (r < tree.length) {
    let cur = tree[r];
    r++; // 收集的连续水果种类大于2之前,始终扩张窗口
    if (map[cur]) {
      map[cur]++;
    } else {
      map[cur] = 1;
      count++; // 增加目前收集的水果类型
    }
    while (count > 2) {
      // 收集的连续水果种类大于2,缩小窗口
      map[tree[l]]--;
      if (!map[tree[l]]) count--; // 减少目前收集的水果类型
      l++;
    }
    res = Math.max(res, r - l);
  }
  return res;
};
239. 滑动窗口最大值

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回滑动窗口中的最大值。

滑动窗口的位置                最大值
---------------               -----
[1  3  -1] -3  5  3  6  7       3
 1 [3  -1  -3] 5  3  6  7       3
 1  3 [-1  -3  5] 3  6  7       5
 1  3  -1 [-3  5  3] 6  7       5
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7
窗口最开始从0扩张到k后,之后就一直维持k的大小,一步一步往后移,直到无法移动为止
i+1>=k   window      window对应的nums值
f        [ 0 ]       [ 1 ]
f        [ 1 ]       [ 3 ]
t        [ 1, 2 ]    [ 3, -1 ]
t        [ 1, 2, 3 ] [ 3, -1, -3 ]
t        [ 4 ]       [ 5 ]
t        [ 4, 5 ]    [ 5, 3 ]
t        [ 6 ]       [ 6 ]
t        [ 7 ]       [ 7 ]
/**
 * @param {number[]} nums [1,3,-1,-3,5,3,6,7]
 * @param {number} k 3
 * @return {number[]} 7
 */
var maxSlidingWindow = function (nums, k) {
  let window = [];
  let res = [];
  for (let i = 0; i < nums.length; i++) {
    // 先把滑动窗口之外的踢出
    if (window[0] !== undefined && window[0] <= i - k) window.shift();
    // 保证队首是最大的
    while (nums[window[window.length - 1]] <= nums[i]) window.pop();
    window.push(i);
    if (i + 1 >= k) res.push(nums[window[0]]);
  }
  return res;
};

七、leetcode - 矩阵

74. 搜索二维矩阵

编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:

每行中的整数从左到右按升序排列。

每行的第一个整数大于前一行的最后一个整数。

输入: matrix = [
                    [1, 3, 5, 7 ],
                    [10,11,16,20],
                    [23,30,34,60]
                ], target = 3
输出: true
搜索过程,从左下角23开始,23大于3,
向上缩小为10,10大于3,
向上缩小为1,1小于3,
向右扩大为3,3等于3,结束查找

23
10
1
3
/**
 * @param {number[][]} matrix
 * @param {number} target
 * @return {boolean}
 */
var searchMatrix = function (matrix, target) {
  let x = matrix.length - 1,
    y = 0;
  while (x >= 0 && y < matrix[0].length) {
    if (matrix[x][y] === target) {
      return true;
    } else if (matrix[x][y] > target) {
      x--;
    } else {
      y++;
    }
  }
  return false;
};

八、leetcode - 栈和队列

20. 有效的括号

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。

[ '(' ]
[]
[ '[' ]
[]
[ '{' ]
[]
/**
 * @param {string} s "()[]{}"
 * @return {boolean} true
 */
var isValid = function (s) {
  let map = { "{": "}", "(": ")", "[": "]" };
  let stack = [];
  for (let i of s) {
    if (map[i]) {
      stack.push(i);
    } else {
      if (map[stack[stack.length - 1]] === i) {
        stack.pop();
      } else {
        return false;
      }
    }
  }
  return stack.length === 0;
};
155. 最小栈
输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]

输出:
[null,null,null,null,-3,null,0,-2]

解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.
最小栈打印结果:
[ -2 ]
[ -2, -2 ]
[ -2, -2, -3 ]
/**
 * initialize your data structure here.
 */
var MinStack = function () {
  this.stack = [];
  this.minStack = [];
};

/**
 * @param {number} val
 * @return {void}
 */
MinStack.prototype.push = function (val) {
  this.stack.push(val);
  let topOfMinStack = this.minStack[this.minStack.length - 1];
  if (this.minStack.length === 0 || val < topOfMinStack) {
    this.minStack.push(val);
  } else {
    this.minStack.push(topOfMinStack);
  }
};

/**
 * @return {void}
 */
MinStack.prototype.pop = function () {
  this.stack.pop();
  this.minStack.pop();
};

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

/**
 * @return {number}
 */
MinStack.prototype.getMin = function () {
  return this.minStack[this.minStack.length - 1];
};

/**
 * Your MinStack object will be instantiated and called as such:
 * var obj = new MinStack()
 * obj.push(val)
 * obj.pop()
 * var param_3 = obj.top()
 * var param_4 = obj.getMin()
 */
739. 每日温度

请根据每日 气温 列表 temperatures ,请计算在每一天需要等几天才会有更高的温度。如果气温在这之后都不会升高,请在该位置用 0 来代替。

出栈     stack的值      stack       res
        [ 73 ]         [ 0 ]       [ 0, 0, 0, 0, 0, 0, 0, 0 ]
1-0     [ 74 ]         [ 1 ]       [ 1, 0, 0, 0, 0, 0, 0, 0 ]
2-1     [ 75 ]         [ 2 ]       [ 1, 1, 0, 0, 0, 0, 0, 0 ]
        [ 75, 71 ]     [ 2, 3 ]    [ 1, 1, 0, 0, 0, 0, 0, 0 ]
        [ 75, 71, 69 ] [ 2, 3, 4 ] [ 1, 1, 0, 0, 0, 0, 0, 0 ]
5-4 5-3 [ 75, 72 ]     [ 2, 5 ]    [ 1, 1, 0, 2, 1, 0, 0, 0 ]
6-5 6-2 [ 76 ]         [ 6 ]       [ 1, 1, 4, 2, 1, 1, 0, 0 ]
        [ 76, 73 ]     [ 6, 7 ]    [ 1, 1, 4, 2, 1, 1, 0, 0 ]
/**
 * @param {number[]} temperatures [73,74,75,71,69,72,76,73]
 * @return {number[]} [1,1,4,2,1,1,0,0]
 */
var dailyTemperatures = function (temperatures) {
  let len = temperatures.length;
  let res = new Array(len).fill(0);
  let stack = [];
  for (let i = 0; i < len; i++) {
    while (
      stack.length &&
      temperatures[i] > temperatures[stack[stack.length - 1]]
    ) {
      let top = stack.pop();
      // 当前下标减去之前记录的下标
      res[top] = i - top;
    }
    stack.push(i);
    stack1.push(temperatures[i]);
  }
  return res;
};
232. 用栈实现队列

用栈先进后出的方式来实现队列先进先出的效果

var MyQueue = function () {
  this.stack1 = []; // 用于入队
  this.stack2 = []; // 用于出队
};

/**
 * @param {number} x
 * @return {void}
 */
MyQueue.prototype.push = function (x) {
  this.stack1.push(x);
};

/**
 * @return {number}
 */
MyQueue.prototype.pop = function () {
  // 将入队栈中的数据导入到出队栈中
  if (!this.stack2.length) {
    while (this.stack1.length) {
      this.stack2.push(this.stack1.pop());
    }
  }
  return this.stack2.pop();
};

/**
 * @return {number}
 */
MyQueue.prototype.peek = function () {
  if (!this.stack2.length) {
    while (this.stack1.length) {
      this.stack2.push(this.stack1.pop());
    }
  }
  // 跟pop相比,只是不出队
  return this.stack2[this.stack2.length - 1];
};

/**
 * @return {boolean}
 */
MyQueue.prototype.empty = function () {
  // 入队栈和出队栈都为空时,队列为空
  return !this.stack1.length && !this.stack2.length;
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * var obj = new MyQueue()
 * obj.push(x)
 * var param_2 = obj.pop()
 * var param_3 = obj.peek()
 * var param_4 = obj.empty()
 */
225. 用队列实现栈

用队列先进先出的方式来实现栈先进后出的效果

一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时在去弹出元素就是栈的顺序了。

/**
 * Initialize your data structure here.
 */
var MyStack = function () {
  this.queue = [];
};

/**
 * Push element x onto stack.
 * @param {number} x
 * @return {void}
 */
MyStack.prototype.push = function (x) {
  this.queue.push(x);
};

/**
 * Removes the element on top of the stack and returns that element.
 * @return {number}
 */
MyStack.prototype.pop = function () {
  let size = this.queue.length;
  while (size-- > 1) {
    this.queue.push(this.queue.shift());
  }
  return this.queue.shift();
};

/**
 * Get the top element.
 * @return {number}
 */
MyStack.prototype.top = function () {
  const x = this.pop();
  this.queue.push(x);
  return x;
};

/**
 * Returns whether the stack is empty.
 * @return {boolean}
 */
MyStack.prototype.empty = function () {
  return !this.queue.length;
};

/**
 * Your MyStack object will be instantiated and called as such:
 * var obj = new MyStack()
 * obj.push(x)
 * var param_2 = obj.pop()
 * var param_3 = obj.top()
 * var param_4 = obj.empty()
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值