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

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

2 <= start.length <= 100000。

0 <= starti <= 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)=8且n=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),其中n为start数组长度。

• 二分验证 :每次验证需要遍历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
相关推荐
噢,我明白了3 小时前
java中唯一键和幂等键的应用
java·后端
GreenTea3 小时前
我把 Agent 的 while 循环拆掉了:一种你可能没想到的 Agent 架构
前端·后端·架构
考虑考虑3 小时前
synchronized字符串常量
java·后端·java ee
颜进强4 小时前
16 · NestJS LifecycleEvents 生命周期事件:五个钩子、三条边界,和 rag-server 的优雅停机
前端·后端·ai编程
GetcharZp4 小时前
定位不再一个个吐坐标:英伟达 LocateAnything 上手全攻略
后端
郑州光合科技余经理5 小时前
同城电商系统:库存变更怎么同步到订单
java·开发语言·前端·后端·uni-app·php·ai编程
我叫黑大帅5 小时前
Go日志库工程选型与逃逸分析评测报告
后端·面试·go
IT_陈寒8 小时前
JavaScript闭包的这个坑,我居然今天才爬出来
前端·人工智能·后端
Thneonl8 小时前
消息队列选型决策树:RabbitMQ vs Kafka vs Redis Streams
后端·架构