代码练习 | 豆包MarsCode AI刷题

68 阅读3分钟

给定一个数组values,其中values[i]表示第i个观光景点的评分。我们需要找到一对景点(i, j)i < j),使得观光组合得分最大。观光组合得分定义为values[i] + values[j] + i - j,即两个景点评分之和减去它们之间的距离(用下标差表示)。

算法思路

这个问题可以通过贪心算法来解决。因为我们需要找到两个景点,使得它们的评分之和减去它们之间的距离最大。我们可以观察到,对于每个景点j,我们可以找到一个最佳的i,使得values[i] + values[j] + i - j最大。可以拆分看成(values[i]+i) + (values[j]-j) 我们只需要分别求出对应最大值就行了。

  1. 初始化:我们初始化两个变量,max_i_value用于存储 j 之前value[i]+i最大得分,max_score用于存储全局最大的观光组合得分。max_i_value初始值为values[0].

  2. 遍历数组:从第二个景点开始遍历数组,对于每个景点j,我们尝试更新max_i_value。对于每个j,我们有两种选择:

    • 选择j作为第二个景点,那么第一个景点应该是之前找到的最佳景点i,使得values[i] + values[j] + i - j最大。由于i是固定的,我们可以计算出这个固定的i使得得分最大的值,即max_i_value + values[j] - j
    • 选择j作为第一个景点,那么我们需要找到一个最佳的ii < j),使得values[i] + values[j] + i - j最大。但是,由于我们已经遍历到了j,我们可以假设j是当前最佳的第二个景点,那么我们可以计算出这个固定的j使得得分最大的值,即values[j] + j
  3. 更新最大得分:对于每个j,我们计算出以j为第二个景点的最大得分,并与当前的max_score比较,如果更大,则更新max_score

  4. 返回结果:遍历结束后,max_score就是所有可能观光组合中的最大得分。

代码实现

以下是这个问题的Python代码实现:

def solution(values: list) -> int:
    n = len(values)
    if n < 2:
        return 0  # 如果数组长度小于2,无法形成组合,返回0或其他适当值
    
    max_i_value = values[0] + 0                  #此项为j之前最大value[i]+i  初始化为第一个
    max_score = values[0]+values[1] +0 - 1       #全局最大值  初始化为第一和第二
    
    for j in range(1,len(values)):                   #从第二个开始遍历
        current_value = values[j] -j                #当前values[j] - j 值               
        
        max_score = max(max_score, max_i_value + current_value)   更新最大数
        
        max_i_value = max(max_i_value, values[j]+j)     #更新最大的value[i]+i
    
    return max_score

总结

这个算法的核心思想是贪心,即在每一步选择当前最优的解,以期望达到全局最优解。通过一次遍历数组,我们可以找到所有可能观光组合中的最大得分。这种方法的时间复杂度为O(n),空间复杂度为O(1),非常高效。