LeetCode 632.最小区间

本文深入解析LeetCode第632题“最小区间”的解题思路,采用排序与离散化策略,通过示例代码详细阐述了如何找到覆盖所有列表元素的最小范围,为算法爱好者提供了一种高效求解方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
LeetCode 632.最小区间
解题思路:排序、离散化
把所有数字按照数值大小从小到大排序,但是每个携带属于哪个k(行)
然后把排序后的数字,离散化。例如: [34,56,10000]离散后,为[0,1,2]
若有相同的数字要记录不同的k(属于哪个行)。
然后每个离散后的数字以此为起点,找一个满足条件的区间
 */
func smallestRange(nums [][]int) []int {
	rowLen := len(nums)
	nodes := make([]*node, 0)
	for i:=0; i<rowLen; i++ {
		colLen := len(nums[i])
		for j:=0; j<colLen; j++ {
			node := &node{nums[i][j], i}
			nodes = append(nodes, node)
		}
	}
	//排序
	sort.Sort(nodeHandler{nodes:nodes, By: func(p, q *node) bool {
		return p.v < q.v
	}})
	nodeLen := len(nodes)
	//离散化后数据
	mapSli := make([]Map, 0)
	//val->离散化的下标
	mapping := make(map[int]int, 0)
	//离散下标记录
	mapCnt := 0
	//离散化
	for i:=0; i<nodeLen; i++ {
		if _, ok := mapping[nodes[i].v]; !ok {
			Map := Map{Pos:make([]int, 0), Val:nodes[i].v}
			Map.Pos = append(Map.Pos, nodes[i].p)
			mapSli = append(mapSli, Map)
			mapping[nodes[i].v] = mapCnt
			mapCnt++
		} else {
			mapSli[mapping[nodes[i].v]].Pos = append(mapSli[mapping[nodes[i].v]].Pos, nodes[i].p)
		}
	}
	//找出最小区间
	L, R := mapSli[0].Val, mapSli[mapCnt-1].Val
	for j:=0; j<mapCnt; j++ {
		r := check(j, rowLen, mapSli)
		if r == -1 {
			continue
		}
		idx := mapSli[j].Val
		if r != -1 {
			r = mapSli[r].Val
			if R-L > r-idx {
				L, R = idx, r
			} else if R-L == r-idx {
				if idx < L {
					L, R = idx, r
				}
			}
		}
	}
	return []int{L ,R}
}

func check(l , k int, mapSli []Map) int {
	mapp := make(map[int]int, 0)
	sliLen := len(mapSli)
	for i:=l; i<sliLen; i++ {
		posLen := len(mapSli[i].Pos)
		for j:=0; j<posLen; j++ {
			if _, ok := mapp[mapSli[i].Pos[j]]; !ok {
				mapp[mapSli[i].Pos[j]] = 1
			}
			if len(mapp) == k {
				return i
			}
		}
	}
	return -1
}

type node struct {
	v, p int
}

type nodeHandler struct {
	nodes []*node
	By func(p, q *node) bool
}

func (n nodeHandler) Less(i, j int)  bool {
	return  n.By(n.nodes[i], n.nodes[j])
}

func (n nodeHandler) Swap(i, j int)  {
	n.nodes[i], n.nodes[j] = n.nodes[j], n.nodes[i]
}

func (n nodeHandler) Len() int {
	return len(n.nodes)
}

type Map struct {
	Pos []int
	Val int
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值