当前位置: 面试刷题>> 汇总区间(经典算法150题)


题目描述

题目:汇总区间

给定一个无重复元素的整数数组 nums,返回该数组所有可能的 连续子数组(至少包含两个元素)的 区间汇总 的列表。每个区间 [start, end] 表示该区间内所有整数的和。

注意

  • 你可以假设 nums 中的元素都是正整数。
  • 区间 [start, end] 表示 nums 中索引从 startend(包含 startend)的连续子数组。
  • 区间 [start, end] 的汇总为 nums[start] + nums[start + 1] + ... + nums[end]

示例 1:

输入: nums = [0,1,2,2,3]
输出: [["0->2","2->2","3"]]
解释: 区间 [0,2] 的和是 3,区间 [2,2] 的和是 2,区间 [3] 的和是 3(单独列出)。
注意,单个元素也视为一个有效的子数组。但题目要求至少包含两个元素,所以这里只列出包含两个或更多元素的区间。
注意:根据题目要求,这里我们仅列出包含至少两个元素的区间汇总。

示例 2:

输入: nums = [2,3,4,2,5]
输出: [["2->4","5"]]
解释: 区间 [2,4] 的和是 11,区间 [5] 的和是 5。

PHP 示例代码

function summaryRanges($nums) {
    $result = [];
    $start = $nums[0];
    $n = count($nums);
    
    for ($i = 1; $i < $n; $i++) {
        if ($nums[$i] != $nums[$i - 1] + 1) {
            if ($start == $nums[$i - 1]) {
                $result[] = strval($start);
            } else {
                $result[] = $start . "->" . $nums[$i - 1];
            }
            $start = $nums[$i];
        }
    }
    
    // 处理最后一个区间
    if ($start == $nums[$n - 1]) {
        $result[] = strval($start);
    } else {
        $result[] = $start . "->" . $nums[$n - 1];
    }
    
    // 过滤出包含至少两个元素的区间
    $filteredResult = array_filter($result, function($item) {
        return strpos($item, "->") !== false;
    });
    
    return $filteredResult;
}

// 示例用法
$nums = [0,1,2,2,3];
print_r(summaryRanges($nums));

注意:PHP 示例中,我按照题目要求进行了实现,但示例输出与题目描述稍有出入(题目要求至少两个元素,但示例1中包含了单个元素的区间)。因此,在最终返回前,我添加了一个过滤步骤来仅保留包含至少两个元素的区间。

Python 示例代码

def summaryRanges(nums):
    if not nums:
        return []
    
    result = []
    start = nums[0]
    
    for i in range(1, len(nums)):
        if nums[i] != nums[i-1] + 1:
            if start == nums[i-1]:
                result.append(str(start))
            else:
                result.append(f"{start}->{nums[i-1]}")
            start = nums[i]
    
    # 处理最后一个区间
    if start == nums[-1]:
        result.append(str(start))
    else:
        result.append(f"{start}->{nums[-1]}")
    
    # 过滤出包含至少两个元素的区间
    return [item for item in result if "->" in item]

# 示例用法
nums = [0,1,2,2,3]
print(summaryRanges(nums))

JavaScript 示例代码

function summaryRanges(nums) {
    if (!nums.length) return [];
    
    let result = [];
    let start = nums[0];
    
    for (let i = 1; i < nums.length; i++) {
        if (nums[i] !== nums[i - 1] + 1) {
            if (start === nums[i - 1]) {
                result.push(start.toString());
            } else {
                result.push(`${start}->${nums[i - 1]}`);
            }
            start = nums[i];
        }
    }
    
    // 处理最后一个区间
    if (start === nums[nums.length - 1]) {
        result.push(start.toString());
    } else {
        result.push(`${start}->${nums[nums.length - 1]}`);
    }
    
    // 过滤出包含至少两个元素的区间
    return result.filter(item => item.includes("->"));
}

// 示例用法
const nums = [0,1,2,2,3];
console.log(summaryRanges(nums));

以上代码均实现了题目要求的功能,并给出了示例用法。注意,在 PHP 示例中,我添加了一个额外的过滤步骤来确保只返回包含至少两个元素的区间汇总,以符合题目要求。在 Python 和 JavaScript 示例中,我也通过列表推导/数组过滤实现了相同的功能。

推荐面试题