有空更新系列 - 练手算法 - go(一)

package main

import (
   "errors"
   "fmt"
)

/**
栈/队列类型 - 简单题

题目:
设计一个有getMin功能的栈
实现一个特殊的栈,既要实现栈的功能,又要能够实现弹出栈中最小元素的操作(只取一次最小值)

时间复杂度:
pop,push,getMin时间复杂度都是O(1)
设计的栈类型可以使用现成的栈结构
 */

func main() {
   fmt.Println("test start")
   // 拿到问题先写解

   /**
   思路:
      操作为O(1)的都会消耗较大的空间,所以这种思路朝创建空间去想
      栈的特性:压入,弹出,先进后出
      双桶最小记录原理:
         创建两个桶,压入规则:压入一个数,比最小桶的顶部元素小则两个桶都压入,比最小桶的顶部元素大则只压入到数据桶
                 弹出规则:需要弹出一个最小的数,则需要对比最小桶和数据桶顶部元素的大小,
                     如果数据桶顶部元素不等于最小桶顶部元素,则直接弹出数据桶顶部元素
                     如果数据桶顶部元素等于最小桶顶部元素,则再将最小桶顶部元素也弹出
                     获取到最小元素
    */

   // 测试数据: 200, 70, 250, 50, 48, 39, 84, 34, 90, 56, 25
   testData := []int64{200, 70, 250, 50, 48, 39, 84, 34, 90, 56, 25}
   bucket := NewBucket()
   for _, value := range testData{
      _ = bucket.Push(value)
   }

   fmt.Printf("bucketMin:%v|bucketData:%v", bucket.bucketMin, bucket.bucketData)
   fmt.Println()

   minData, _ := bucket.GetMin()
   fmt.Printf("minData: %v", minData)
   fmt.Println()

   for len(bucket.bucketData) != 0 {
      popData, _ := bucket.Pop()
      fmt.Printf("pop:%v", popData)
      fmt.Println()
   }

   fmt.Println("test end")
}

/**
双桶最小记录原理实现
 */

type Bucket struct {
   bucketMin []int64  // 最小数桶
   bucketData []int64 // 所有数据桶
}

// 创建栈
func NewBucket() (bucket *Bucket)  {
   return &Bucket{
      bucketMin:  []int64{},
      bucketData: []int64{},
   }
}

func(b *Bucket) Push(element int64) (err error)  {
   // 压入数据为最小的时候则将最小桶和数据桶都压入对应的桶内
   if len(b.bucketMin) == 0 {
      b.bucketMin = append(b.bucketMin, element)
   } else if min, _ := b.GetMin(); element <= min {
      b.bucketMin = append(b.bucketMin, element)
   }

   b.bucketData = append(b.bucketData, element)
   return nil
}

func(b *Bucket) Pop() (minData int64, err error)  {
   minLen := len(b.bucketMin)
   dataLen := len(b.bucketData)

   if dataLen == 0 {
      return 0, errors.New("pop Exception")
   }

   min, err := b.GetMin()
   if err != nil {
      return 0, errors.New("pop Exception")
   }

   data := b.bucketData[dataLen - 1]
   if min == data {
      b.bucketMin = append(b.bucketMin[:minLen - 1], b.bucketMin[minLen:]...)
   }

   b.bucketData = append(b.bucketData[:dataLen - 1], b.bucketData[dataLen:]...)
   return data, nil
}

func(b *Bucket) GetMin() (min int64, err error)  {
   minLen := len(b.bucketMin)
   if minLen == 0 {
      return 0, errors.New("GetMin Exception")
   }
   return b.bucketMin[minLen - 1], nil
}

 

输出结果:

test start
bucketMin:[200 70 50 48 39 34 25]|bucketData:[200 70 250 50 48 39 84 34 90 56 25]
minData: 25
pop:25
pop:56
pop:90
pop:34
pop:84
pop:39
pop:48
pop:50
pop:250
pop:70
pop:200
test end

  

posted @ 2022-02-25 21:29  祝哥哥很快乐  阅读(25)  评论(0)    收藏  举报