首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

2024-06-01:用go语言,给定一个从0开始索引的整数数组 nums 、两个正整数 k 和 dist 。 数组的代价是该数

2024-06-01:用go语言,给定一个从0开始索引的整数数组 nums 、两个正整数 k 和 dist 。

数组的代价是该数组中的第一个元素。

问题要求将数组 nums 分割成 k 个连续且不重叠的子数组,

同时确保第二个到第k个子数组的第一个元素与它前面的子数组的最后一个元素的距离不超过 dist 。

换句话说,要把数组分割成这样的子数组:

nums[0..(i1 - 1)], nums[i1..(i2 - 1)], ..., nums[ik-1..(n - 1)],

并且满足 ik-1 - i1 <= dist 。

问题的目标是求得这些子数组的代价之和的最小值。

输入:nums = [1,3,2,6,4,2], k = 3, dist = 3。

输出:5。

答案2024-06-01:

chatgpt

题目来自leetcode3013。

大体步骤如下:

1.创建两个堆结构l和r,其中l是最大堆,r是最小堆,所有元素取反存储。这两个堆用于维持子数组之间的距离。

2.初始化堆l和r,将数组nums的一部分元素(前dist+2个)依次加入堆l中。

3.对堆l进行调整,保持其大小不超过k,如果超过则将多出的部分元素从堆l移至堆r中。

4.遍历数组nums,从第dist+2个元素开始,进行子数组的调整:

• 移除out元素,根据其大小从堆l或堆r中移除。

• 添加in元素,根据其大小添加到堆l或堆r中。

• 维护堆的大小,保持堆l的大小在k-1和k+1之间。

• 计算当前的代价和mn,并更新为当前的最小值。

5.最后返回数组的第一个元素与最小代价和mn的和作为最终结果。

总的时间复杂度分析:

• 初始化堆的时间复杂度为 O(dist).

• 遍历数组的时间复杂度为 O(n), 其中对堆的操作的时间复杂度为 O(log k). 因此,总的时间复杂度为 O(n * log k).

总的额外空间复杂度分析:

• 除了输入参数外,算法使用了两个堆结构及相关变量来维护子数组的信息。

• 堆结构的空间复杂度为 O(k)。

• 因此,总的额外空间复杂度为 O(k).

Go完整代码如下:

package main

import (

"container/heap"

"fmt"

"sort"

)

func minimumCost(nums []int, k int, dist int) int64 {

k--

l := &lazyHeap{todo: map[int]int{}} // 最大堆

r := &lazyHeap{todo: map[int]int{}} // 最小堆,所有元素取反

for _, x := range nums[1 : dist+2] {

l.push(x)

}

for l.size > k {

r.push(-l.pop())

}

mn := l.sum

for i := dist + 2; i < len(nums); i++ {

// 移除 out

out := nums[i-dist-1]

if out <= l.top() {

l.del(out)

} else {

r.del(-out)

}

// 添加 in

in := nums[i]

if in < l.top() {

l.push(in)

} else {

r.push(-in)

}

// 维护大小

if l.size == k-1 {

l.push(-r.pop())

} else if l.size == k+1 {

r.push(-l.pop())

}

mn = min(mn, l.sum)

}

return int64(nums[0] + mn)

}

type lazyHeap struct {

sort.IntSlice

todo map[int]int

size int // 实际大小

sum  int // 实际元素和

}

func (h lazyHeap) Less(i, j int) bool { return h.IntSlice[i] > h.IntSlice[j] } // 最大堆

func (h *lazyHeap) Push(v any)        { h.IntSlice = append(h.IntSlice, v.(int)) }

func (h *lazyHeap) Pop() any          { a := h.IntSlice; v := a[len(a)-1]; h.IntSlice = a[:len(a)-1]; return v }

func (h *lazyHeap) del(v int)         { h.todo[v]++; h.size--; h.sum -= v } // 懒删除

func (h *lazyHeap) push(v int) {

if h.todo[v] > 0 {

h.todo[v]--

} else {

heap.Push(h, v)

}

h.size++

h.sum += v

}

func (h *lazyHeap) pop() int { h.do(); h.size--; v := heap.Pop(h).(int); h.sum -= v; return v }

func (h *lazyHeap) top() int { h.do(); return h.IntSlice[0] }

func (h *lazyHeap) do() {

for h.Len() > 0 && h.todo[h.IntSlice[0]] > 0 {

h.todo[h.IntSlice[0]]--

heap.Pop(h)

}

}

func main() {

nums := []int{1, 3, 2, 6, 4, 2}

fmt.Println(minimumCost(nums, 3, 3))

}

在这里插入图片描述

  • 发表于:
  • 原文链接https://page.om.qq.com/page/O3Yklmrh0hsRzEgl6aC-szIg0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

相关快讯

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券