力扣228.汇总区间(java 双指针法)

题目描述:

给定一个 无重复元素 的 有序 整数数组 nums 。

返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums 的数字 x 。

列表中的每个区间范围 [a,b] 应该按如下格式输出:

“a->b” ,如果 a != b
“a” ,如果 a == b
力扣228.汇总区间(java 双指针法)_第1张图片

分析与代码

“滑动窗口”实质也是双指针的灵活运用,抽象出来的关键操作就是:

1.如何根据题目实际需求形成一个可以变化范围的数据集合(个人的理解,也就是所说的“滑动窗口”)
2.如和根据实际需求对“可变化范围的数据集合”中的数据进行操作

再看本题目,我们不难发现,实际上我们只需要每次找出滑动窗口的窗口值即可,具体的:

1.我们根据,若相邻两元素相差1则可以动态维护“窗口”,实际代码操作中我们利用循环动态维护两指针(设为low与high),low每次记录当前的位置,若满足条件则high往后移动(直接看代码)
2.每次直接取出“窗口值”添加到集合中即可
3.注意:本题中还存在左右窗口重合的情况(即区间内只有唯一一元素),此时在取出并做添加操作时要注意判断是否low < high

代码:

class Solution {
    //Time Complexity: O(N)
    //Space Complexity: O(1)
    public List<String> summaryRanges(int[] nums) {
    	//定义结果集合
    	List<String> res = new ArrayList<>();
    	int i = 0;
    	int len = nums.length;
    	while (i < len) {
    		int low = i;	//low每次指向当前位置
    		i++;
    		//只要相差1就往后面“滑动”
    		while (i < len && nums[i] - nums[i - 1] == 1) {
    			i++;
    		}
    		//"窗口的右端"为i-1
    		int high = i - 1;
    		//添加两个“窗口值”到结果集中
    		StringBuffer temp = new StringBuffer(Integer.toString(nums[low]));
    		//防止“窗口值”重合
            if (low < high) {
                temp.append("->");
                temp.append(Integer.toString(nums[high]));
            }
            res.add(temp.toString());
    	}
    	 return res;
    }
}    

你可能感兴趣的:(力扣题目,leetcode,java,算法)