有关栈

113 阅读2分钟

栈不仅是经典的数据结构还是很多算法题的解法。

题目一:225. 用队列实现栈

tips: 注意队列是先进先出,尾进头出。栈的pop操作要将尾部的元素移动到首部,然后取出。

// 用队列实现栈
func Constructor() MyStack {
   return MyStack{
      queue: make([]int, 0),
   }
}

func (this *MyStack) Push(x int) {
   this.queue = append(this.queue, x)
}

func (this *MyStack) Pop() int {
   if this.Empty() {
      return 0
   }
   n := len(this.queue) - 1
   //队列是先进先出,尾进头出,因此只能从queue头部取值,将尾部的值放到头部即可
   for n != 0 {
      val := this.queue[0]
      this.queue = this.queue[1:]
      this.queue = append(this.queue, val)
      n--
   }
   val := this.queue[0]
   this.queue = this.queue[1:]
   return val
}

func (this *MyStack) Top() int {
   val := this.Pop()
   if val != 0 {
      this.queue = append(this.queue, val)
   }
   return val
}

func (this *MyStack) Empty() bool {
   if len(this.queue) == 0 {
      return true
   }
   return false
}

题目二:155. 最小栈

tips: 维护一个当前元素对应的最小值的栈。 stack:[2,3,4,4,5,6,1,7,2],min_stack:[2,2,2,2,2,2,1,1,1]

// 155. 最小栈
type MinStack struct {
   stack    []int
   minStack []float64
}

func MinStackConstructor() MinStack {
   return MinStack{
      stack:    []int{},
      minStack: []float64{math.MaxFloat64},
   }
}

func (this *MinStack) Push(x int) {
   this.stack = append(this.stack, x)
   top := this.minStack[len(this.minStack)-1]
   this.minStack = append(this.minStack, math.Min(float64(x), top))
}

func (this *MinStack) Pop() {
   this.stack = this.stack[:len(this.stack)-1]
   this.minStack = this.minStack[:len(this.minStack)-1]
}

func (this *MinStack) Top() int {
   return this.stack[len(this.stack)-1]
}

func (this *MinStack) GetMin() int {
   return int(this.minStack[len(this.minStack)-1])
}

题目三:739. 每日温度

tips: 需要找到左边或者右边第一个比当前位置的大或者小的题目,则可以考虑使用单调栈。

// 739. 每日温度
// 时间复杂度O(n)
// 空间复杂度O(n)
func dailyTemperatures(temperatures []int) []int {
   if len(temperatures) == 0 {
      return nil
   }
   var res = make([]int, len(temperatures))
   var stack []int
   for i, t := range temperatures {
      for len(stack) > 0 && t > temperatures[stack[len(stack)-1]] {
         preIndex := stack[len(stack)-1]
         res[preIndex] = i - preIndex
         stack = stack[:len(stack)-1]
      }
      stack = append(stack, i)
   }
   return res
}

题目四:151. 反转字符串中的单词

tips: 需要反转顺序的时候,可以考虑使用栈。

// 151. 反转字符串中的单词
func reverseWords(s string) string {
   var stack []string
   idx := 0
   for idx < len(s) {
      for idx < len(s) && s[idx] == ' ' {
         idx++
      }
      if idx == len(s) {
         break
      }
      left := idx
      for idx < len(s) && s[idx] != ' ' {
         idx++
      }
      stack = append(stack, s[left:idx])
   }
   wordsBuilder := strings.Builder{}
   for i := len(stack) - 1; i >= 0; i-- {
      wordsBuilder.WriteString(stack[i])
      if i != 0 {
         wordsBuilder.WriteString(" ")
      }
   }
   return wordsBuilder.String()
}

题目五:20. 有效的括号

tips: 需要考虑左右匹配的时候,可以考虑使用栈。

// 20. 有效的括号
func isValid(s string) bool {
   stack := []string{string(s[0])}
   l := len(stack)
   for i, c := range s {
      if i == 0 {
         continue
      }
      stack = append(stack, string(c))
      l = len(stack)
      for l > 1 && (stack[l-1] == ")" && stack[l-2] == "(" ||
         stack[l-1] == "]" && stack[l-2] == "[" ||
         stack[l-1] == "}" && stack[l-2] == "{") {
         stack = stack[0 : l-2]
         l = len(stack)
      }
   }
   if l == 0 {
      return true
   }
   return false
}

题目六:394. 字符串解码

tips: 依次按照某种匹配规则(字符对,包括空格符)对某块单元处理,可以考虑使用栈。

// 394. 字符串解码
func decodeString(s string) string {
   var stack []byte
   for i := range s {
      if s[i] != ']' {
         stack = append(stack, s[i])
      } else {
         j := len(stack) - 1
         for j >= 0 {
            if stack[j] == '[' {
               break
            }
            j--
         }
         // 字符块
         temp := make([]byte, len(stack)-j-1)
         copy(temp, stack[j+1:])
         k := j
         j--
         for j >= 0 {
            if stack[j] < '0' || stack[j] > '9' {
               break
            }
            j--
         }
         // 字符块前的数字
         cnt, _ := strconv.Atoi(string(stack[j+1 : k]))
         stack = stack[0 : j+1]
         for cnt > 0 {
            stack = append(stack, temp...)
            cnt--
         }
      }
   }
   return string(stack)
}