go语言实现最小区间问题

问题:

你有 k 个 非递减排列 的整数列表。找到一个 最小 区间,使得 k 个列表中的每个列表至少有一个数包含在其中。

我们定义如果 b-a < d-c 或者在 b-a == d-c 时 a < c,则区间 [a,b] 比 [c,d] 小。

示例 

输入:nums = [[4,10,15,24,26], [0,9,12,20], [5,18,22,30]]
输出:[20,24]
解释: 
列表 1:[4, 10, 15, 24, 26],24 在区间 [20,24] 中。
列表 2:[0, 9, 12, 20],20 在区间 [20,24] 中。
列表 3:[5, 18, 22, 30],22 在区间 [20,24] 中。

思想 

排序加滑动窗口来解决这个问题,利用go语言自带的map记录每个区间的值并且区间的值做键,区间索引做值,这样避免重复并且保存区间的最小值和最大值。在定义left左边界索引,right为右边界索引。在这个区间中遍历,直到找到最小区间为止。

代码

func smallestRange(nums [][]int) []int {
    size :=len(nums)
    hashMap := map[int][]int{}
    xMin, xMax := math.MaxInt32, math.MinInt32
    for i :=0 ;i < size; i++ {
        for _,x := range nums[i] {
            hashMap[x] = append(hashMap[x],i)
            xMin = min(xMin,x)
            xMax = max(xMax,x)
        }
    }
    left,right := xMin, xMin-1
    inSide := 0
    indicate := make([]int, size)
    bestLeft,bestRight := xMin, xMax
    for right < xMax {
        right++
        if len(hashMap[right]) > 0 {
            for _,x := range hashMap[right] {
                indicate[x]++
                if indicate[x] == 1 {
                    inSide++
                }
            }
            for inSide == size {
                if bestRight - bestLeft > right - left {
                    bestRight = right
                    bestLeft = left
                }
                for _,x := range hashMap[left]{
                    indicate[x]--
                    if indicate[x] == 0{
                        inSide--
                    }
                }
                left++
            }
        }
    } 
    ans := []int{bestLeft,bestRight}
    return ans
}
func min(x int, y int ) int {
    if x > y{
        return y
    }
    return x
}
func max(x int, y int) int {
    if x > y{
        return x
    }
    return y
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值