插入区间的思路探讨与源码
插入区间的题目如下图,该题属于数组类型的题目,主要考察对于数组本身的理解和遍历技巧的优化使用。本文的题目作者想到2种方法,分别是模拟遍历方法和排序法,其中模拟遍历方法使用java进行编写,而排序法使用Python进行编写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
本人认为该题目可以模拟遍历的方法,首先找到区间的左右边界值,然后初始化列表和标记,开始进行遍历,如果列表内数组的左边界比需要插入的数组的右边界要大,并且标记值为false,则把结果列表里增加一个插入的数组,并且再把当前原始列表也加入到结果列表里。如果原始数组的右边界小于需要插入数组的左边界,那么把原始数组直接加入到结果列表里。否则就取边界值更新为扩大范围的区间,即左边变成更小,右边变成更大的。最终合并区间并遍历结果列表得到新的数组列表范围。那么按照这个思路我们的Java代码如下:
#喷火龙与水箭龟
class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
int a = newInterval[0];
int b = newInterval[1];
List<int[]> outList = new ArrayList<int[]>();
boolean flag = false;
for (int[] interval : intervals) {
if (interval[0] > b) {
if (! flag) {
outList.add(new int[]{a, b});
flag = true;
}
outList.add(interval);
} else if (interval[1] < a) {
outList.add(interval);
} else {
a = Math.min(a, interval[0]);
b = Math.max(b, interval[1]);
}
}
if (! flag) {
outList.add(new int[]{a, b});
}
int[][] tp = new int[outList.size()][2];
for (int ir = 0; ir < outList.size(); ir++) {
tp[ir] = outList.get(ir);
}
return tp;
}
}
显然,我们看到模拟遍历的方法效率不错,同时还可以使用排序的方法进行处理,首先把需要插入的区间合并到原始区间里面,然后进行排序,排序以后开始进行变量初始化操作,然后开始遍历,把每个子区间拿出来,把里面的子区间的左边界的值和区间边界值进行比较,把区间边界值进行范围拓展,否则就把区间结果插入到最终的结果里去,并且更新a和b的值,最后返回结果列表即可。所以按照这个思路就可以解决,下面是Python代码部分:
#喷火龙与水箭龟
class Solution:
def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
intervals.append(newInterval)
intervals.sort()
resFinal = []
if not intervals:
return resFinal
a = intervals[0][0]
b = intervals[0][-1]
lenNum = len(intervals)
for ir in range(lenNum):
list = intervals[ir]
if list[0] <= b:
b = max(b, list[-1])
continue
else:
resFinal.append([a, b])
a = list[0]
b = list[1]
resFinal.append([a, b])
return resFinal
从结果来说java版本的模拟遍历方法的效率不错,而python版本的排序方法的速度一般,但应该是有更多的方法可以进一步提速的,希望朋友们能够多多指教,非常感谢。