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

package main

import (
	"errors"
	"fmt"
)

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

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

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

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

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

	// 测试数据: 1,5,2,6,8,9,4,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
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

祝哥哥学习好

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值