2025-04-13:范围内整数的最大得分。用go语言,给定一个整数数组 start 和一个整数 d,这代表了 n 个区间 [start[i], start[i

2025-04-13:范围内整数的最大得分。用go语言,给定一个整数数组 start 和一个整数 d,这代表了 n 个区间 [start[i], start[i] + d]。你的任务是从每个区间中选择一个整数,使得所选整数之间的最小绝对差值尽可能大。返回所选整数能够得到的最大最小绝对差值。

2 <= start.length <= 100000。

0 <= start[i] <= 1000000000。

0 <= d <= 1000000000。

输入: start = [6,0,3], d = 2。

输出: 4。

解释:

可以选择整数 8, 0 和 4 获得最大可能得分,得分为 min(|8 - 0|, |8 - 4|, |0 - 4|),等于 4。

题目来自leetcode3280。

根据题目描述和提供的代码,解决该问题的步骤如下:

步骤解析

  1. 排序预处理

    首先对输入的start数组进行排序。排序后区间顺序被调整为升序排列,便于后续的贪心策略按顺序处理每个区间。例如,输入[6,0,3]排序后变为[0,3,6],对应的区间是[0,2][3,5][6,8]

  2. 二分搜索框架

    目标是找到最大的最小绝对差值(记为score)。采用二分法确定该值:

    初始范围 :二分的上限设为(start[n-1] + d - start[0]) / (n-1)。这假设所有区间均匀分布时的最大可能差值。例如,当区间总长度为(8-0)=8n=3时,初始上限为8/2=4,与样例输出一致。

    验证函数 :对每个候选的score,判断是否能在所有区间中选出满足条件的数。若存在,尝试更大的score;否则减小。

  3. 贪心验证策略

    在每次二分验证时,从第一个区间开始,依次为每个区间选择尽可能小的数,同时满足以下条件:

    • 当前数必须大于等于区间左端点(即≥start[i])。

    • 当前数与前一个数的差值至少为score

    具体实现中,变量x记录前一个区间的选择,每次更新为max(x+score, start[i])。若此值超过区间右端点(start[i]+d),则说明当前score过大,验证失败。

  4. 边界处理

    当所有区间均满足条件时,返回true,表示可以尝试更大的score;否则返回false。最终通过二分逼近最大的可行score


复杂度分析

时间复杂度

排序 :时间复杂度为O(n log n),其中nstart数组长度。

二分验证 :每次验证需要遍历n个区间,时间复杂度O(n)。二分次数为O(log C)C为可能的score最大值,如1e9)。
总时间复杂度O(n log n + n log C),适用于n ≤ 1e5的规模。

空间复杂度

仅需常数空间存储变量和排序(原地排序),因此总空间复杂度为O(1)


关键点

贪心策略的有效性 :通过按序处理区间并尽量选择最小的数,确保后续区间有更大的选择空间,从而最大化最小差值。

二分法的应用 :将最优化问题转化为判定问题,通过高效验证函数快速收敛到最优解。

初始范围的合理性:通过均匀分布假设设定二分上限,避免无效搜索。

Go完整代码如下:

go 复制代码
package main

import (
	"fmt"
	"slices"
	"sort"
	"math"
)

func maxPossibleScore(start []int, d int) int {
	slices.Sort(start)
	n := len(start)
	// 二分最小的不满足要求的 score+1,最终得到的答案就是最大的满足要求的 score
	return sort.Search((start[n-1]+d-start[0])/(n-1), func(score int) bool {
		score++
		x := math.MinInt
		for _, s := range start {
			x = max(x+score, s) // x 必须 >= 区间左端点 s
			if x > s+d {
				return true
			}
		}
		return false
	})
}

func main() {
	start := []int{6,0,3}
	d := 2
	results := maxPossibleScore(start,d)
	fmt.Println(results)
}

Python完整代码如下:

python 复制代码
# -*-coding:utf-8-*-

import math

def maxPossibleScore(start, d):
    start.sort()
    n = len(start)
    if n == 1:
        return 0
    end = (start[-1] + d - start[0]) // (n - 1)
    left, right = 0, end
    ans = 0
    while left <= right:
        mid = (left + right) // 2
        score_plus_1 = mid + 1
        x = -math.inf
        possible = True
        for s in start:
            x = max(x + score_plus_1, s)
            if x > s + d:
                possible = False
                break
        if not possible:
            right = mid - 1
            ans = mid
        else:
            left = mid + 1
    return ans

# 测试示例
start = [6, 0, 3]
d = 2
print(maxPossibleScore(start, d))  # 输出结果为3
相关推荐
你们补药再卷啦1 小时前
springboot 项目 jmeter简单测试流程
java·spring boot·后端
网安密谈1 小时前
SM算法核心技术解析与工程实践指南
后端
bobz9651 小时前
Keepalived 检查和通知脚本
后端
AKAMAI1 小时前
教程:在Linode平台上用TrueNAS搭建大规模存储系统
后端·云原生·云计算
盘盘宝藏1 小时前
idea搭建Python环境
后端·intellij idea
喵手1 小时前
Spring Boot 项目基于责任链模式实现复杂接口的解耦和动态编排!
spring boot·后端·责任链模式
大鹏dapeng1 小时前
使用gone v2 的 Provider 机制升级改造 goner/xorm 的过程记录
后端·设计模式·go
雷渊1 小时前
介绍一下RocketMQ的几种集群模式
java·后端·面试
讳疾忌医_note1 小时前
别再错用 C++ 线程池!正确姿势与常见误区大揭秘
后端
快乐源泉1 小时前
【设计模式】参数校验逻辑复杂,代码长?用责任链
后端·设计模式·go