溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript數據結構之棧的用法案例

發布時間:2020-10-10 18:05:00 來源:億速云 閱讀:150 作者:小新 欄目:web開發

這篇文章主要介紹了JavaScript數據結構之棧的用法案例,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。

先來看一道題

Leetcode 32 Longest Valid Parentheses (最長有效括號)

給定一個只包含 '(' 和 ')' 的字符串,找出最長的包含有效括號的子串的長度。

示例 1:

輸入: "(()"
輸出: 2
解釋: 最長有效括號子串為 "()"

示例 2:

輸入: ")()())"
輸出: 4
解釋: 最長有效括號子串為 "()()"

這道題可以用動態規劃來做,也能用簡潔明了的棧來解決。

什么是棧?

棧是一種先進后出(LIFO)的有序集合,新添加的元素在棧頂,舊元素在棧底。

以下圖為例,1、2、3、4、5、6、7先后進棧:

JavaScript數據結構之棧的用法案例

創建棧

創建一個類來表示棧:

class Stack {
    // 初始化類,創建數組 items 存放入棧元素
    constructor() {
        this.items = [];
    }
    // push 方法進行元素入棧(可同時入棧一或多個元素),無返回值
    push() {
        this.items.push(...arguments);
    }
    // pop 方法出棧一個元素,返回出棧元素
    pop() {
        return this.items.pop();
    }
    // peek 方法返回棧頂元素,不對棧本身做任何操作
    peek() {
        return this.items[this.items.length-1];
    }
    // size 方法返回棧內元素個數
    size() {
        return this.items.length;
    }
    // isEmpty 方法查看棧是否為空,返回布爾值
    isEmpty() {
        return this.items.length == 0;
    }
    // clear 方法清空棧,無返回值
    clear() {
        this.items = [];
    }
    // print 方法打印棧內元素
    print() {
        console.log(this.items.toString());
    }
}

// 測試 
let stack = new Stack();
stack.push(1,2,3,4);
stack.print(); // 1,2,3,4
stack.isEmpty(); // false
stack.size(); // 4
stack.pop(); // 4
stack.peek(); // 3
stack.clear();
注意

因為 JavaScript 的類內暫時無法定義私有成員,所以可以在類外訪問到存儲棧元素的數組 items,這個操作是很危險的。

stack.items; // [1, 2, 3, 4]

這時可以使用閉包IIFE進行避免,這是一個很無奈的辦法:

let Stack = (function () {
    // 使用 WeakMap 存儲數組(數組存放進棧元素)
    let items = new WeakMap();
    class Stack {
        constructor() {
            items.set(this, []);
        }
        push() {
            items.get(this).push(...arguments);
        }
        // 其他方法
    }
    return Stack;
})();

let s = new Stack();
// 無法訪問到 items
s.items; // undefined

WeakMap: WeakMap是類似Map的鍵值對集合,但WeakMap的鍵是弱引用的,只要不存在引用,垃圾回收機制就會回收掉占用的內存,相當于自動刪除,而不用手動刪除。

用棧解題

思路:

  1. 變量start存放有效括號起始下標,maxLen存放最大長度;

  2. 棧只存放左括號的下標,遇到左括號,將其下標存入棧中;

  3. 遇到右括號,若此時棧為空,跳過本次循環并更新start;若棧不為空,則棧頂元素出棧;

  4. 棧頂元素出棧后,若棧為空,則計算當前下標和start的距離,并更新maxLen;

  5. 棧頂元素出棧后,若棧不為空,則計算當前下標和棧頂存放的下標的距離,并更新maxLen;

  6. 循環遍歷直至結束。

function test(str) {
    let stack = new Stack();
    let start = 0;
    let maxLen = 0;

    for(let i=0; i<str.length; i++) {
        // 如果是左括號,下標入棧
        if (str[i] == '(') {
            stack.push(i);
        } else {
            // 如果是右括號
            /* 棧內為空,說明本次有效括號匹配已結束,跳過本次循環并更新 start */
            if (stack.isEmpty()) {
                start = i+1;
                continue;
            } else {
                // 棧內不為空,則出棧一個左括號進行匹配
                stack.pop();
                // 棧頂元素出棧后,棧為空
                if (stack.isEmpty()) {
                    // 根據當前下標和 start 去更新 maxLen
                    maxLen = Math.max(maxLen, i-start+1);
                } else {
                    // 棧不為空,根據當前下標和棧頂存放的下標去更新 maxLen
                    maxLen = Math.max(maxLen, i-stack.peek());
                }
                
            }
        }       
    }
    
    return maxLen;
}

test('(()'); // 2
test(')()())'); // 4

感謝你能夠認真閱讀完這篇文章,希望小編分享JavaScript數據結構之棧的用法案例內容對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,遇到問題就找億速云,詳細的解決方法等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女