恋上数据结构与算法三(栈、队列)


  • 一种特殊的线性表,只能在一端进行操作,后进先出原则
struct Stack<Element> {
    private var stack = [Element]()
    var isEmpty: Bool {
        return stack.isEmpty
    }
    var size: Int {
        return stack.count
    }
    mutating func push(item: Element) {
        stack.append(item)
    }
    mutating func pop() -> Element {
        return stack.removeLast()
    }
    //栈顶元素
    var peek: Element? {
        return stack.last
    }
}

队列

一种特殊的线性表,只能头尾两端操作,先进先出原则
双端队列:能在头尾两端添加、删除的队列

class Queue<Element> {
    var array: [Element]
    init() {
        array = []
    }
    var isEmpty: Bool {
        return array.isEmpty
    }
    var size: Int {
        return array.count
    }
    //队尾入队
    func enQueueRear(_ x: Element) {
        array.append(x)
    }
    //队头入队
    func enQueueFront(_ x: Element) {
        array.insert(x, at: 0)
    }
    //队尾出队
    func deQueueRear() -> Element {
        return array.removeLast()
    }
    //队头出队
    func deQueueFront() -> Element {
        return array.removeFirst()
    }
    //队列头元素
    var front: Element? {
        return array.first
    }
    //队尾元素
    var rear: Element? {
        return array.last
    }
}

循环队列:用数组实现并且优化之后的队列

练习

1.有效的括号

给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串

/*
 1.遇见左字符,将左字符入栈
 2.遇见右字符
 如果栈是空的,说明括号无效
 如果栈不为空,将栈顶字符出栈,与右字符匹配
 如果左右字符不匹配,说明括号无效
 如果左右字符匹配,继续下一个字符
 3.所有字符遍历完
 栈为空,说明括号有效
 栈不为空,说明括号无效
 */
let mapper = ["(":")","[":"]","{":"}"]
func isValid(_ s: String) -> Bool {
    //栈
    var stack = [String]()
    for chr in s {
        //遇见左字符
        if mapper.keys.contains(chr.description) {
            stack.append(chr.description)
        }
        //遇见右字符
        else {
            if stack.isEmpty {
                return false
            } else {
                //stack出栈
                let element = stack.removeLast()
                if mapper[element] != chr.description {
                    return false
                }
            }
        }
    }
    return stack.isEmpty
}

2.括号的分数

给定一个平衡括号字符串 S,按下述规则计算该字符串的分数:

() 得 1 分。
AB 得 A + B 分,其中 A 和 B 是平衡括号字符串。
(A) 得 2 * A 分,其中 A 是平衡括号字符串。
"(())" 输出: 2
"()()" 输出: 2
"(()(()))" 输出: 6

/*
 用栈记录下方便查上次遍历的
 (()) level = 1 val = 1<<1 = 2
 ((())) level = 2 val = 1<<2 = 4
 (((()))) level = 3 val = 1<<3 = 8
 遍历后放入栈,遇到")"的时候看上一个是否是"("再计算值
 */
func scoreOfParentheses(_ S: String) -> Int {
    var level = 0
    var stack = [String]()
    var amount = 0
    for chr in S {
        if chr.description == "(" {
            level += 1
            stack.append(chr.description)
        } else {
            level -= 1
            print(stack.last)
            if stack.last == "(" {
                amount += (1<<level)
            }
            stack.append(chr.description)
        }
    }
    return amount
}

3.逆波兰表达式求值
4.基本计算器
5.用栈实现队列

/*
 准备2个栈 inStack outStack
 入队时,push到inStack
 出队时
 outStack为空,将inStack所有元素逐一弹出,push到outStack,outStack弹出栈顶元素
 outStack不为空,outStack弹出栈顶元素
 */
class MyQueue {
    var inStack: Stack<Int>
    var outStack: Stack<Int>
    /** Initialize your data structure here. */
    init() {
        inStack = Stack()
        outStack = Stack()
    }
    /** Push element x to the back of queue. */
    func push(_ x: Int) {
        inStack.push(item: x)
    }
    /** Removes the element from in front of queue and returns that element. */
    func pop() -> Int {
        if outStack.isEmpty {
            while !inStack.isEmpty {
                let element = inStack.pop()
                outStack.push(item: element)
            }
        }
        return outStack.pop()
    }
    /** Get the front element. */
    func peek() -> Int {
        if outStack.isEmpty {
            while !inStack.isEmpty {
                let element = inStack.pop()
                outStack.push(item: element)
            }
        }
        return outStack.peek!
    }
    /** Returns whether the queue is empty. */
    func empty() -> Bool {
        return inStack.isEmpty && outStack.isEmpty
    }
}

6.用队列实现栈

class MyStack {
    var queue = Queue()
    /** Initialize your data structure here. */
    init() {}
    /** Push element x onto stack. */
    func push(_ x: Int) {
        queue. enQueueRear(x)
    }
    /** Removes the element on top of the stack and returns that element. */
    func pop() -> Int {
        var queue2 = Queue()
        while queue.size > 1 {
            queue2. enQueueRear(queue. deQueueFront())
        }
        var temp = queue
        queue = queue2
        queue2 = temp
        return queue2.front!
    }
    /** Get the top element. */
    func top() -> Int {
        var queue2 = Queue()
        while queue.size > 1 {
            queue2. enQueueRear(queue. deQueueFront())
        }
        var val = queue.front
        queue2.push(queue. deQueueFront())
        queue = queue2
        return val!
    }
    /** Returns whether the stack is empty. */
    func empty() -> Bool {
        return queue.isEmpty
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,841评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,415评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,904评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,051评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,055评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,255评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,729评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,377评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,517评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,420评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,467评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,144评论 3 317
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,735评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,812评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,029评论 1 256
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,528评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,126评论 2 341