国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

每周一練 之 數(shù)據(jù)結(jié)構(gòu)與算法(Stack)

hzx / 2282人閱讀

摘要:二實(shí)現(xiàn)一個(gè)棧,并實(shí)現(xiàn)下面方法添加一個(gè)新元素到棧頂。移除棧頂?shù)脑兀瑫r(shí)返回被移除的元素。十進(jìn)制轉(zhuǎn)換為二進(jìn)制請(qǐng)輸入正確的數(shù)值方法簡(jiǎn)單實(shí)現(xiàn)下面這個(gè)方法,其實(shí)不太好,因?yàn)闆]有怎么用到這次要練習(xí)的棧方法,哈哈。

最近公司內(nèi)部在開始做前端技術(shù)的技術(shù)分享,每周一個(gè)主題的 每周一練,以基礎(chǔ)知識(shí)為主,感覺挺棒的,跟著團(tuán)隊(duì)的大佬們學(xué)習(xí)和復(fù)習(xí)一些知識(shí),新人也可以多學(xué)習(xí)一些知識(shí),也把團(tuán)隊(duì)內(nèi)部學(xué)習(xí)氛圍營造起來。

我接下來會(huì)開始把每周一練的題目和知識(shí)整理一下,便于思考和鞏固,就像今天這篇開始。

學(xué)習(xí)的道路,很漫長,要堅(jiān)持,希望大家都能掌握自己喜歡的技術(shù),和自己需要的技術(shù)。

歡迎查看我的 個(gè)人主頁 &&  個(gè)人博客 && 個(gè)人知識(shí)庫 && 微信公眾號(hào)“前端自習(xí)課”

本周練習(xí)內(nèi)容:數(shù)據(jù)結(jié)構(gòu)與算法 —— Stack

這些都是數(shù)據(jù)結(jié)構(gòu)與算法,一部分方法是團(tuán)隊(duì)其他成員實(shí)現(xiàn)的,一部分我自己做的,有什么其他實(shí)現(xiàn)方法或錯(cuò)誤,歡迎各位大佬指點(diǎn),感謝。

一、棧有什么特點(diǎn),生活中有什么例子?

棧( stack )又稱堆棧,是一種后進(jìn)先出的有序集合,其中一端為棧頂,另一端為棧底,添加元素(稱為壓棧/入棧或進(jìn)棧)時(shí),將新元素壓入棧頂,刪除元素(稱為出棧或退棧)時(shí),將棧底元素刪除并返回被刪除元素。

特點(diǎn):先進(jìn)后出,后進(jìn)先出

例子:一疊書、一疊盤子。

二、實(shí)現(xiàn)一個(gè)棧,并實(shí)現(xiàn)下面方法

push(element):添加一個(gè)新元素到棧頂。

pop():移除棧頂?shù)脑兀瑫r(shí)返回被移除的元素。

peek():返回棧頂?shù)脑兀粚?duì)棧做任何修改 (這個(gè)方法不會(huì)移除棧頂?shù)脑兀瑑H僅返回它)。

isEmpty():如果棧沒有任何元素就返回 true,否則返回 false

clear():移除棧里面的所有元素。

size():返回棧里的元素個(gè)數(shù)。這個(gè)方法與數(shù)組的 length 屬性類似。

方法1:ES6實(shí)現(xiàn)

class Stack {
    constructor (){
        this.items = []
    }
    push( element ){
        this.items.push(element)
    }
    pop(){
        return this.items.pop()
    }
    peek(){
        return this.items[this.items.length - 1]
    }
    isEmpty(){
        return this.items.length === 0
    }
    clear(){
        this.items = []
    }
    size(){
        return this.items.length
    }
}

上面實(shí)現(xiàn)的方式雖然簡(jiǎn)單,但是內(nèi)部 items 屬性是公共的,為了滿足面向?qū)ο笞兂伤接行缘脑瓌t,我們應(yīng)該讓 items 作為私有屬性,因此我們可以使用 ES6 中 SymbolWeakMap 來實(shí)現(xiàn):

方法2:使用 ES6 的 Symbol 基本數(shù)據(jù)類型實(shí)現(xiàn)
知識(shí)點(diǎn)復(fù)習(xí):ES6 中的 Symbol 介紹

const _items = Symbol()
class Stack {
    constructor (){
        this[_items] = []
    }
    push (element){
        this[_items].push(element)
    }
    // 剩下方法和第一種實(shí)現(xiàn)的差不多,這里省略
    // 只要把前面方法中的 this.items 更改為 this[_items]
}

方法3:使用 ES6 的 WeakMap 實(shí)現(xiàn)
知識(shí)點(diǎn)復(fù)習(xí):ES6 中的 WeakMap 介紹

const items = new WeakMap()
class Stack {
    constructor (){
        items.set(this, [])
    }
    push (element){
        let item = items.get(this)
        item.push(element)
    }
    // 剩下方法和第一種實(shí)現(xiàn)的差不多,這里省略
    // 只要把前面方法中的獲取 this.items 的方式,更改為 items.get(this) 獲取
}
三、編寫一個(gè)函數(shù),實(shí)現(xiàn)十進(jìn)制轉(zhuǎn)二進(jìn)制

題目意思很簡(jiǎn)單,就是十進(jìn)制轉(zhuǎn)二進(jìn)制,但是在實(shí)際工作開發(fā)中,我們更愿意實(shí)現(xiàn)的是任意進(jìn)制轉(zhuǎn)任意進(jìn)制,不過呢,我們還是以解決問題為首要目標(biāo)呀。

當(dāng)然,業(yè)務(wù)需求可以直接使用 toString(2) 方法,但是為了練習(xí),咱還是不這么用咯。

方法1:使用前面定義的 Stack 類
這里使用前面題目中定義的 Stack 類。

/**
 * 十進(jìn)制轉(zhuǎn)換為二進(jìn)制
 * @param {Number} bit 
 */
function bitset (bit){
    if(bit == 0) return "0"
    if(!/^[0-9]+.?[0-9]*$/.test(bit)){
        return new Error("請(qǐng)輸入正確的數(shù)值!")
    }

    let stack = new Stack(), result = ""
    while (bit > 0){
        stack.push(bit % 2)
        bit = Math.floor(bit / 2)
    }
    while (!stack.isEmpty()){
        result += stack.pop().toString()
    }
    return result

}

方法2:簡(jiǎn)單實(shí)現(xiàn)
下面這個(gè)方法,其實(shí)不太好,因?yàn)闆]有怎么用到這次要練習(xí)的方法,哈哈。

/**
 * 十進(jìn)制轉(zhuǎn)換為二進(jìn)制
 * @param {Number} bit 
 */
function bitset (bit){
    if(bit == 0) return "0"
    if(!/^[0-9]+.?[0-9]*$/.test(bit)){
        return new Error("請(qǐng)輸入正確的數(shù)值!")
    }

    let arr = []
    while(bit > 0){
        arr.push(bit % 2)
        bit = Math.floor(bit / 2)
    }
    return arr.reverse().join("")
}

另外可以參考:wikiHow - 從十進(jìn)制轉(zhuǎn)換為二進(jìn)制。

四、編寫一個(gè)函數(shù),實(shí)現(xiàn)檢驗(yàn)圓括號(hào)順序的有效性

主要目的就是:該函數(shù)接收一個(gè)圓括號(hào)字符串,判斷里面的括號(hào)順序是否有效,如果有效則返回 true 反之 false
如:

( -> false

() -> true

(() -> false

()) -> false

()) -> false

(((()()))()) -> true

這個(gè)題目實(shí)現(xiàn)的主要方法是:遍歷字符串,先排除錯(cuò)誤情況,然后將 ( 入棧保存,將 ) 入棧匹配前一個(gè)元素是否是 ( ,如果是,則 pop() 前一個(gè)元素 (,如果不是,則 push() 這個(gè) ) 入棧,最終查看棧是否為空,若是則檢驗(yàn)成功,否則失敗。

方法1:使用前面定義的 Stack 類
這里使用前面題目中定義的 Stack 類。

/**
 * 檢驗(yàn)圓括號(hào)順序的有效性
 * @param {String} str 
 */
function validParentheses (str){
    if(!str || str.length === 0 || str[0] === ")") return false

    let stack = new Stack()
    str.split("").forEach(char => {
        let status = stack.peek() === "(" && char === ")"
        status ? stack.pop() : stack.push(char)
    })
    return stack.isEmpty()
}

方法2:出入棧操作

/**
 * 檢驗(yàn)圓括號(hào)順序的有效性
 * @param {String} str 
 */
function validParentheses (str){
    if(!str || str.length === 0 || str[0] === ")") return false

    let arr = []
    for(let i = 0; i < str.length ; i++){
        str[i] === "(" ? arr.push(str[i]) : arr.pop()
    }
    return arr.length === 0
}
五、改造題二,添加一個(gè) min 函數(shù)來獲得棧中最小元素
步驟 數(shù)據(jù)棧 輔助棧 最小值
1.push 3 3 0 3
2.push 4 3, 4 0, 0 3
3.push 2 3, 4, 2 0, 0, 2 2
4.push 1 3, 4, 2 ,1 0, 0, 2, 3 1
5.pop 3, 4, 2 0, 0, 2 2
6.pop 3, 4 0, 0 3
7.push 3, 4 ,0 0, 0, 2 0

使用示例如下:

let stack = new Stack();
stack.push(3);
console.log("After push 3, Min item is", stack.min());
stack.push(4);
console.log("After push 4, Min item is", stack.min());
stack.push(2);
console.log("After push 2, Min item is", stack.min());
stack.push(1);
console.log("After push 1, Min item is", stack.min());
stack.pop();
console.log("After pop, Min item is", stack.min());
stack.pop();
console.log("After pop, Min item is", stack.min());
stack.push(0);
console.log("After push 0, Min item is", stack.min());

提示:利用輔助棧(Web 端可利用數(shù)組),每次對(duì)棧 push/pop 元素時(shí),也同時(shí)更新輔助棧(存儲(chǔ)最小元素的位置)

方法1:小操作

class Stack {
  constructor() {
    this.items = [];
    this.minIndexStack = [];
  }

  push(element) {
    this.items.push(element);
    let minLen = this.minIndexStack.length;
    let minItemIndex = this.minIndexStack[minLen - 1];
    if(minLen === 0 || this.items[minItemIndex] > item) {
      this.minIndexStack.push(this.items.length - 1);
    } else {
      this.minIndexStack.push(minItemIndex);
    }
  }

  pop() {
    this.minIndexStack.pop();
    return this.items.pop();
  }
  
  min() {
    let len = this.minIndexStack.length;
    return (len > 0 && this.items[this.minIndexStack[len - 1]]) || 0;
  }

  peek() {
    return this.items[this.items.length - 1];
  }
  
  // 省略其它方法
}

方法2:與方法1中push實(shí)現(xiàn)的差異

class Stack {
    constructor (){
        this.items = [] // 數(shù)據(jù)棧
        this.arr = []   // 輔助棧
    }
    push( element ){
        this.items.push(element)
        let min = Math.min(...this.items)
        this.arr.push( min === element ? this.size() - 1 : 0)
    }
    pop(){
        this.arr.pop()
        return this.items.pop()
    }
    peek(){
        return this.items[this.items.length - 1]
    }
    isEmpty(){
        return this.items.length === 1
    }
    clear(){
        this.items = []
    }
    size(){
        return this.items.length
    }
    min (){
        let last = this.arr[this.arr.length - 1]
        return this.items[last]
    }
}
下周預(yù)告

下周將練習(xí)隊(duì)列(Queue) 的題目,開始翻起算法書籍學(xué)習(xí)咯。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/103515.html

相關(guān)文章

  • 周一 數(shù)據(jù)結(jié)構(gòu)算法(Queue)

    摘要:與堆棧區(qū)別隊(duì)列的操作方式和堆棧類似,唯一的區(qū)別在于隊(duì)列只允許新數(shù)據(jù)在后端進(jìn)行添加。移除隊(duì)列的第一項(xiàng),并返回被移除的元素。三使用隊(duì)列計(jì)算斐波那契數(shù)列的第項(xiàng)。前兩項(xiàng)固定為,后面的項(xiàng)為前兩項(xiàng)之和,依次向后。 showImg(https://segmentfault.com/img/remote/1460000019005270); 這是第二周的練習(xí)題,這里補(bǔ)充下咯,五一節(jié)馬上就要到了,自己的...

    anquan 評(píng)論0 收藏0
  • 周一 數(shù)據(jù)結(jié)構(gòu)算法(Set)

    摘要:一集合是什么與它相關(guān)數(shù)學(xué)概念有哪些解題集合定義集合是一種包含不同元素的數(shù)據(jù)結(jié)構(gòu)。集合中的元素稱為成員,集合最重要的兩個(gè)特點(diǎn)集合中的成員是無序集合中不存在相同成員即無序且唯一。 showImg(https://segmentfault.com/img/remote/1460000019005270); 這是第四周的練習(xí)題,五一放假結(jié)束,該收拾好狀態(tài)啦。 下面是之前分享的鏈接: ...

    silvertheo 評(píng)論0 收藏0
  • 周一 數(shù)據(jù)結(jié)構(gòu)算法(Tree)

    摘要:假設(shè)一個(gè)二叉搜索樹具有如下特征節(jié)點(diǎn)的左子樹只包含小于當(dāng)前節(jié)點(diǎn)的數(shù)。所有左子樹和右子樹自身必須也是二叉搜索樹。代碼實(shí)現(xiàn)二叉樹節(jié)點(diǎn)定義來源驗(yàn)證二叉搜索樹解析 showImg(https://segmentfault.com/img/remote/1460000019005270); 這是第六周的練習(xí)題,最近加班比較多,上周主要完成一篇 GraphQL入門教程 ,有興趣的小伙伴可以看下哈。 ...

    zhonghanwen 評(píng)論0 收藏0
  • 周一 數(shù)據(jù)結(jié)構(gòu)算法(Tree)

    摘要:假設(shè)一個(gè)二叉搜索樹具有如下特征節(jié)點(diǎn)的左子樹只包含小于當(dāng)前節(jié)點(diǎn)的數(shù)。所有左子樹和右子樹自身必須也是二叉搜索樹。代碼實(shí)現(xiàn)二叉樹節(jié)點(diǎn)定義來源驗(yàn)證二叉搜索樹解析這是第六周的練習(xí)題,最近加班比較多,上周主要完成一篇 GraphQL入門教程 ,有興趣的小伙伴可以看下哈。 下面是之前分享的鏈接: 1.每周一練 之 數(shù)據(jù)結(jié)構(gòu)與算法(Stack) 2.每周一練 之 數(shù)據(jù)結(jié)構(gòu)與算法(LinkedList) 3...

    fizz 評(píng)論0 收藏0
  • 周一 數(shù)據(jù)結(jié)構(gòu)算法(Dictionary 和 HashTable)

    摘要:什么是散列表和散列函數(shù)哈希表,也叫散列表,是根據(jù)關(guān)鍵碼值而直接進(jìn)行訪問的數(shù)據(jù)結(jié)構(gòu)。根據(jù)鍵值從散列表中移除值。請(qǐng)實(shí)現(xiàn)散列表將和存在一個(gè)對(duì)象中即可定義一個(gè)包含和屬性的類并分配到散列表。 showImg(https://segmentfault.com/img/remote/1460000019005270); 這是第五周的練習(xí)題,上周忘記發(fā)啦,這周是復(fù)習(xí) Dictionary 和 Hash...

    eternalshallow 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

hzx

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<