在代碼的世界中,不管是什麼語言,棧其實都是一種很是重要的數據結構。
全球聞名的代碼提問社區stack overflow就以棧(stack)溢出做爲網站名的一個部分。
在寫代碼或者是debug的過程當中,相信你已經感覺到了在函數調用棧的世界蹦蹦跳跳的快樂了。
在學校裏刷oj,刷LeetCode,進入社會參加筆試面試的過程當中,相信你也感覺到了棧的強大和易用。
這篇博文很是適合數據結構基礎很是薄弱的同窗食用,也歡迎基礎紮實的同窗指正和交流。
若是從未感覺過stack的美妙和強大,這篇博文將很是適合你~前端
什麼是棧?git
JavaScript中的Array與棧github
leetcode 棧 解法題目面試
面試題 棧 解法題目segmentfault
下面這個結構你們都熟悉,瞬間體現出棧LIFO的特性。數組
// 定義一個棧 let stack = [1,2,3]; // 入棧 stack.push(4); // stack [1,2,3,4] // 出棧 stack.pop(); // 4 stack [1,2,3]
設計一個支持 push ,pop ,top 操做,並能在常數時間內檢索到最小元素的棧。瀏覽器
push(x) —— 將元素 x 推入棧中。 pop() —— 刪除棧頂的元素。 top() —— 獲取棧頂元素。 getMin() —— 檢索棧中的最小元素。
var MinStack = function() { this.stack = []; }; MinStack.prototype.push = function(x) { this.stack.push(x); }; MinStack.prototype.pop = function() { return this.stack.pop(); }; MinStack.prototype.top = function() { return this.stack[this.stack.length - 1]; }; MinStack.prototype.getMin = function() { return Math.min(...this.stack); };
題目:https://leetcode-cn.com/probl...
解法:https://github.com/FrankKai/l...微信
題目:https://leetcode-cn.com/probl...
題解:https://github.com/FrankKai/l...前端工程師
/** * 解法2:棧 * 1.構建一個棧 * 2.依次入棧全部開括號 * 3.遇到閉括號時與棧頂的開括號匹配 * 3.1若匹配上,出棧並繼續 * 3.2匹配不上,return false * 4.遍歷結束後的棧應該爲空,不然爲無效括號 */ var isValid = function(s) { var bracketsMap = { "(": ")", "{": "}", "[": "]" }; var openBrackets = Object.keys(bracketsMap); var closeBrackets = Object.values(bracketsMap); var stack = []; var sArr = s.split(""); for (var i = 0; i < sArr.length; i++) { if (openBrackets.indexOf(sArr[i]) !== -1) { stack.push(sArr[i]); } else if (closeBrackets.indexOf(sArr[i]) !== -1) { var top = stack[stack.length - 1]; if (sArr[i] === bracketsMap[top]) { stack.pop(); } else { return false; } } } return stack.length === 0; }
/** * @param {string} a * @param {string} b * @return {string} */ var addBinary = function (a, b) { /** * 解法2:棧 * 時間複雜度:O(n) * 性能:56ms, 35.5MB */ let aArr = a.split(""); let bArr = b.split(""); let stack = []; let count = 0; while (aArr.length !== 0 || bArr.length !== 0) { let aPop = aArr.pop() || 0; let bPop = bArr.pop() || 0; let stackBottom = 0; if (stack.length > count) { stackBottom = stack.shift() || 0; } let sum = parseInt(aPop) + parseInt(bPop) + parseInt(stackBottom) if (sum <= 1) { stack.unshift(sum); } else { stack.unshift(sum - 2); stack.unshift(1); } count++; } return stack.join(""); };
題目:https://leetcode-cn.com/probl...
題解:https://github.com/FrankKai/l...數據結構
/** * @param {number[]} A * @return {number[]} */ var sortArrayByParity = function (A) { /** * 棧頭棧尾解法便可 * 偶數棧底推入unshift * 奇數棧頂推入push */ var stack = []; for (var i = 0; i < A.length; i++) { if (A[i] % 2 === 0) { stack.unshift(A[i]); } else { stack.push(A[i]); } } return stack; };
題目:https://leetcode-cn.com/probl...
題解:https://github.com/FrankKai/l...
/** * @param {number[][]} intervals * @return {number[][]} */ var merge = function (intervals) { /** * 解法1:排序 + 棧 * 性能:88ms 36.3MB * 思路: * 推入區間 空棧 或者 arr[0]大於棧最後一個區間閉 * 覆蓋重疊 arr[0]小於棧最後一個區間閉 * */ intervals.sort((a, b) => a[0] - b[0]); let stack = []; for (let i = 0; i < intervals.length; i++) { let currrentInterval = intervals[i]; let stackLastItem = stack[stack.length - 1]; if (stack.length === 0 || currrentInterval[0] > stackLastItem[1]) { stack.push(currrentInterval); } else if (currrentInterval[0] <= stackLastItem[1]) { stackLastItem[1] = Math.max(stackLastItem[1], currrentInterval[1]); } } return stack; };
題目:https://leetcode-cn.com/probl...
題解:https://github.com/FrankKai/l...
var sortColors = function (nums) { /** * 解法1:遞歸 棧 * 性能:64ms 35.1MB */ var length = nums.length; var countHead = arguments[1] || 0; var countTail = arguments[2] || 0; for (var i = countHead || 0; i < length - countTail; i++) { if (nums[i] === 0) { countHead++; nums.unshift(nums.splice(i, 1)); // 增長if(i!==0)會下降10ms性能 return sortColors(nums, countHead, countTail); } else if (nums[i] === 2) { countTail++; nums.push(nums.splice(i, 1)); return sortColors(nums, countHead, countTail); } } return nums; }
題目:https://leetcode-cn.com/probl...
題解:https://github.com/FrankKai/l...
/** * @param {number[]} nums * @return {string[]} */ var summaryRanges = function (nums) { /** * 解法1:排序 + 棧 * 性能:52ms 33.7MB */ nums.sort((a, b) => a - b); let stack = []; let result = []; for (let i = 0; i < nums.length; i++) { if (stack.length === 0 || nums[i] - stack[stack.length - 1] === 1) { stack.push(nums[i]); } else { stackToResult(); stack = []; stack.push(nums[i]); } if (i === nums.length - 1) { stackToResult(); } } function stackToResult() { if (stack.length > 1) { result.push(`${stack[0]}->${stack[stack.length - 1]}`); } else { result.push(`${stack[0]}`); } } return result; };
題目:https://leetcode-cn.com/probl...
題解:https://github.com/FrankKai/l...
/** * 解法2:棧 + 遞歸 1132ms 19.96% 59.2MB 11.76% * 思路: * 1.經過shift取出棧底元素 * 2.遍歷剩餘溫度棧內溫度 * 若溫度出現比棧底溫度大者 * 存儲i+1 * 遞歸進行下一次入棧 * 若溫度小於等於棧底溫度 * 若遍歷到最後一個都沒有出現更大的 * 存儲 0 * 進行下一次入棧 * 3.最後一個溫度不管如何都確定是0 */ var dailyTemperatures = function(T) { if (T.length < 1 || T.length > 30000) return false; var result = arguments[1] || []; var bottom = T.shift(); for (var i = 0; i < T.length; i++) { var t = T[i]; if (t > bottom) { result.push(i + 1); return dailyTemperatures(T, result); } else { if (i === T.length - 1) { result.push(0); return dailyTemperatures(T, result); } } } result.push(0); return result; }
實現大整數相加,大於 Number.MAX_VALUE,不能直接使用 BigInt。
/** * 請經過代碼實現大整數(可能比Number.MAX_VALUE大)相加運算 // your code goes here var bigint1 = new BigInt('1231230'); var bigint2 = new BigInt('12323123999999999999999999999999999999999999999999999991'); console.log(bigint1.plus(bigint2)) */
function BigInt(value) { this.value = value; } BigInt.prototype.plus = function (bigint) { let aArr = this.value.split(""); let bArr = bigint.value.split(""); let stack = []; let count = 0; while (aArr.length !== 0 || bArr.length !== 0) { let aPop = aArr.pop() || 0; let bPop = bArr.pop() || 0; let stackBottom = 0; if (stack.length > count) { stackBottom = stack.shift(); } let sum = parseInt(aPop) + parseInt(bPop) + parseInt(stackBottom); if (sum < 10) { stack.unshift(sum); } else if (sum >= 10) { stack.unshift(sum - 10); stack.unshift(1); } count++; } return stack.join(""); };
期待和你們交流,共同進步,歡迎你們加入我建立的與前端開發密切相關的技術討論小組:
- 微信公衆號: 生活在瀏覽器裏的咱們 / excellent_developers
- Github博客: 趁你還年輕233的我的博客
- SegmentFault專欄:趁你還年輕,作個優秀的前端工程師
- Leetcode討論微信羣:Z2Fva2FpMjAxMDA4MDE=(加我微信拉你進羣)
努力成爲優秀前端工程師!