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

举报
福大大架构师每日一题 发表于 2025/04/13 11:28:17 2025/04/13
【摘要】 2025-04-13:范围内整数的最大得分。用go语言,给定一个整数数组 start 和一个整数 d,这代表了 n 个区间 [start[i], start[i] + d]。你的任务是从每个区间中选择一个整数,使得所选整数之间的最小绝对差值尽可能大。返回所选整数能够得到的最大最小绝对差值。2 <= start.length <= 100000。0 <= start[i] <= 1000000...

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完整代码如下:

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完整代码如下:

# -*-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

在这里插入图片描述

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。