代码随想录day30 || 452 引爆气球,435 无重叠区间,763 划分字母区间

452 射爆气球

func findMinArrowShots(points [][]int) int {
	// 思路,尝试按照start asc,end asc 排序一下, 取交集射爆
	if len(points) == 1{
		return 1
	}

	sort.Slice(points, func (i, j int) bool {
		if points[i][0] == points[j][0] {
			return points[i][1] < points[j][1]
		}
		return points[i][0] < points[j][0]
	})

	// 相邻判断交际
	var count int
	var res []int
	for i:=1; i < len(points); {
		res = points[i-1]
		for i < len(points) && res != nil {  // 运行到第k个气球发现没有交集,所以退出,此时i++, i=k+1
			res = intersection(res, points[i])
			i++
			fmt.Println(i, res)
		}
		if i == len(points) && res == nil {
			count++ // 最后一个没有交集需要补上
		}
		count++ // 此时需要一把箭射爆有交集的所有气球
	}

	return count
}
func intersection(x,y []int) []int {
	start := max(x[0], y[0])
	end := min(x[1], y[1])
	if start > end {
		return nil
	}
	return []int{start, end}
}

func max(x,y int) int {
	if x > y {
		return x
	}
	return y
}
func min(x,y int) int {
	if x < y {
		return x
	}
	return y
}

image

// 通过考虑边界简化交集算法
func findMinArrowShots(points [][]int) int {
	// 思路,尝试按照start asc,end asc 排序一下
	if len(points) == 1{
		return 1
	}

	sort.Slice(points, func (i, j int) bool {
		if points[i][0] == points[j][0] {
			return points[i][1] < points[j][1]
		}
		return points[i][0] < points[j][0]
	})

	// 相邻判断交际
	var count int = 1
	for i:=1; i < len(points); i++{
		if points[i][0] > points[i-1][1] { // [1,2], [3,4] 后一个气球左边界大于前一个起球的右边界,没有重叠
			count++
		}else { // 有重叠,则更新边界
			points[i][1] = min(points[i][1], points[i-1][1])
		}
	}

	return count
}
func min (x , y int)int{
	if x < y {
		return x
	}
	return y
}

435 无重叠区间

func eraseOverlapIntervals(intervals [][]int) int {
	// 思路,尝试按照start asc,end asc 排序一下
	if len(intervals) <= 1{
		return 0
	}

	sort.Slice(intervals, func (i, j int) bool {
		if intervals[i][0] == intervals[j][0] {
			return intervals[i][1] < intervals[j][1]
		}
		return intervals[i][0] < intervals[j][0]
	})

	// 相邻判断交际
	var count int
	for i:=1; i < len(intervals); i++{
		if intervals[i][0] >= intervals[i-1][1] {
		}else { // 有重叠,则更新边界
			count++
			intervals[i][1] = min(intervals[i][1], intervals[i-1][1])
		}
	}

	return count
}
func min (x , y int)int{
	if x < y {
		return x
	}
	return y
}

划分字母区间

image

func partitionLabels(s string) []int {
	// 考虑暴力双指针,对于每一个字符,向后面判断是否有重复,没有就开始划分
	if len(s) == 1 {
		return []int{1}
	}

	var dismap = make(map[byte]int) // 保存字母出现的最远位置
	for i:=0; i<len(s); i++ {
		if dismap[s[i]] < i{
			dismap[s[i]] = i
		}
	}

	var disslice []int
	for i := 0; i<len(s); i++ {
		disslice = append(disslice, dismap[s[i]])
	}

	var start, end, m int
	var res []int
	for start < len(s) {
		end = disslice[start]
		m = max(disslice[start: end+1])
		for m > end {
			end = m
			m = max(disslice[start: end+1])
		}
		// 此时end是区间内部最大值(可能多个最大值)
		res = append(res, end - start + 1)
		start = end + 1

	}
	return res
}

func max(list []int) int {
	var m int = math.MinInt
	for _, v := range list {
		if v > m {
			m = v
		}
	}
	return m
}

posted @ 2024-08-15 11:46  周公瑾55  阅读(15)  评论(0)    收藏  举报