目录
- 题目描述和要求
- 示例解释
- 解题思路
- 算法实现
- 复杂度分析
- 测试和验证
- 总结和拓展
- 参考资料
题目描述和要求
给定一个无重复元素的有序整数数组 nums,要求返回恰好覆盖数组中所有数字的最小有序区间范围列表。即,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums 的数字。
列表中的每个区间范围 [a,b] 应该按如下格式输出:
- “a->b”,如果 a != b
- “a”,如果 a == b
示例解释
示例 1:
输入:nums = [0,1,2,4,5,7]
输出:[“0->2”,“4->5”,“7”]
解释:区间范围是:
- [0,2] --> “0->2”
- [4,5] --> “4->5”
- [7,7] --> “7”
示例 2:
输入:nums = [0,2,3,4,6,8,9]
输出:[“0”,“2->4”,“6”,“8->9”]
解释:区间范围是:
- [0,0] --> “0”
- [2,4] --> “2->4”
- [6,6] --> “6”
- [8,9] --> “8->9”
解题思路
一种简单的方法是遍历数组,对连续的数字进行合并形成区间。具体步骤如下:
- 初始化一个结果列表,用于存储最终的区间范围。
- 使用双指针,分别标记区间的起始和结束位置。
- 遍历数组,如果当前数字与前一个数字连续,则更新结束位置;否则,将前一个区间加入结果列表,并更新起始和结束位置。
- 将最后一个区间加入结果列表。
- 返回结果列表。
算法实现
import java.util.ArrayList;
import java.util.List;
public class SummaryRanges {
public List<String> summaryRanges(int[] nums) {
List<String> result = new ArrayList<>();
if (nums == null || nums.length == 0) {
return result;
}
int start = nums[0];
int end = nums[0];
for (int i = 1; i < nums.length; i++) {
if (nums[i] == end + 1) {
end = nums[i];
} else {
if (start == end) {
result.add(Integer.toString(start));
} else {
result.add(start + "->" + end);
}
start = nums[i];
end = nums[i];
}
}
if (start == end) {
result.add(Integer.toString(start));
} else {
result.add(start + "->" + end);
}
return result;
}
}
复杂度分析
- 时间复杂度:O(n),其中 n 为数组的长度。遍历一次数组。
- 空间复杂度:O(1)。除了结果列表外,不需要额外的空间。
测试和验证
编写测试用例对算法进行验证,确保其正确性和健壮性。
public class Main {
public static void main(String[] args) {
SummaryRanges summaryRanges = new SummaryRanges();
int[] nums1 = {0, 1, 2, 4, 5, 7};
System.out.println(summaryRanges.summaryRanges(nums1)); // ["0->2", "4->5", "7"]
int[] nums2 = {0, 2, 3, 4, 6, 8, 9};
System.out.println(summaryRanges.summaryRanges(nums2)); // ["0", "2->4", "6", "8->9"]
}
}
总结和拓展
本题通过简单的数组遍历和区间合并的方式,实现了求解给定有序整数数组的最小区间范围列表。这个算法简单高效,在处理类似问题时是一个不错的选择。
此外,我们也可以考虑优化算法以提高效率,例如使用更高效的数据结构或算法来实现同样的功能。
参考资料
- 《力扣经典150题》
- LeetCode 官方网站