基础算法|区间合并|AcWing 803. 区间合并|2022-11-18

AcWing 803. 区间合并

输入输出学到了!

package main
import (
    "bufio"
    "fmt"
    "math"
    "os"
    "sort"
    "strconv"
    "strings"
)
// 存储区间
type pair struct {
    first int   // 区间左端点
    second int  // 区间右端点
}
// 为了能全局使用
var scanner *bufio.Scanner

func readline() []int {
    scanner.Scan()
    // 将获取的输入按照空格切割,赋值给cutLine
    cutLine := strings.Split(scanner.Text(), " ")
    
    // 创建一个临时切片
    tempSlice := make([]int, len(cutLine))
    
    // 将cutLine的内容赋值给tempSlice
    for i, v := range cutLine {
        temp, _ := strconv.Atoi(v) 
        tempSlice[i] = temp
    }
    return tempSlice
}

func main() {
    scanner = bufio.NewScanner(os.Stdin)
    bs := make([]byte, 2000*1024)   // 扩大,防止输入数据过大爆内存
    scanner.Buffer(bs, len(bs))
    
    // 获取n的输入
    var n = readline()[0]
    
    segs := make([]pair, 0)
    for i:=0;i<n;i++{
        //获取区间输入
        x := readline()
        segs = append(segs, pair{x[0], x[1]})   // 读入每个区间的左右端点
    }
    
    // 调用区间合并模板
    ans := merge(segs)
    fmt.Println(len(ans))
}

// 区间合并模板
func merge(segs []pair) []pair {
    var res []pair
    sort.Slice(segs, func(i, j int) bool {
        // 如果两边左端点相同,那么就按照右端点排序
        if segs[i].first == segs[j].first {
            return segs[i].second < segs[i].second
        } 
        // 优先以左端点大小为排序
        return segs[i].first < segs[j].first
    })
    
    // 从左往右扫描,维护当前区间
    start, end := math.MinInt32, math.MinInt32
    for _, seg := range segs {
        if end < seg.first {    // 当前区间与下一个区间没有交集
            if start != math.MinInt32 {
                res = append(res, pair{start, end})
            }
            start, end = seg.first, seg.second
        } else {    // 当前区间与下一个区间有交集
            if seg.second > end {
                end = seg.second
            }
        }
    }
    
    // 将最后一个区间放进来
    if start != math.MinInt32 {
        res = append(res, pair{start, end})
    }
    return res
}

背诵模板

// 区间合并模板
func merge(segs []pair) []pair {
    var res []pair
    sort.Slice(segs, func(i, j int) bool {
        // 如果两边左端点相同,那么就按照右端点排序
        if segs[i].first == segs[j].first {
            return segs[i].second < segs[i].second
        } 
        // 优先以左端点大小为排序
        return segs[i].first < segs[j].first
    })
    
    // 从左往右扫描,维护当前区间
    start, end := math.MinInt32, math.MinInt32
    for _, seg := range segs {
        if end < seg.first {    // 当前区间与下一个区间没有交集
            if start != math.MinInt32 {
                res = append(res, pair{start, end})
            }
            start, end = seg.first, seg.second
        } else {    // 当前区间与下一个区间有交集
            if seg.second > end {
                end = seg.second
            }
        }
    }
    
    // 将最后一个区间放进来
    if start != math.MinInt32 {
        res = append(res, pair{start, end})
    }
    return res
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值