yankewei / LeetCode

LeetCode 问题的解决方法
MIT License
6 stars 0 forks source link

汇总区间 #166

Open yankewei opened 1 year ago

yankewei commented 1 year ago

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

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

列表中的每个区间范围 [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"

提示:

yankewei commented 1 year ago

这个题思路比较简单,但是要写一个完美无缺且优雅的逻辑需要花一点时间,我的第一版是这样的

class Solution {

    /**
     * @param Integer[] $nums
     * @return String[]
     */
    function summaryRanges($nums) {
        // 首先把这种为空的先判断方便我们后续的逻辑处理
        if (count($nums) === 0) {
            return [];
        }

        $ret = [];

        // 我这里是把左端和右端的元素的值列出来,其实没必要。当时想的 ret 的数组是元素的值,所以没想那么多
        $left = $nums[0];
        $right = $nums[0];

        for ($i = 1; $i < count($nums); $i++) {
            if ($nums[$i] === $right + 1) {
                $right = $nums[$i];
            } else {
                if ($left === $right) {
                    $ret[] = strval($left);
                } else {
                    $ret[] = strval($left) . '->' . strval($right);
                }
                $left = $right = $nums[$i];
            }
        }

        // 下面的逻辑就是为了最后一个元素做的处理,如果最后一个元素和前一个元素是连续的,但是这个连续的处理又不能放在上边的那个循环中,因为是最后一个元素。
        if ($left === $right) {
            $ret[] = strval($left);
        } else {
            $ret[] = strval($left) . '->' . strval($right);
        }

        return $ret;
    }
}

下面是花了些时间做的优化,首先就是想的上边的最后一步其实和循环中的第二个 if 逻辑做的一样的处理,能不能合在一起,就有了下边的相对优雅的代码

class Solution {

    /**
     * @param Integer[] $nums
     * @return String[]
     */
    function summaryRanges($nums) {

        $ret = [];
        $length = count($nums);
        $i = 0;
        while ($i < $length) {
            $left = $i;

            for ($i++; $i < $length && $nums[$i-1] +1 === $nums[$i]; $i++) {

            }

            $item = strval($nums[$left]);
            if ($left < $i-1) {
                $item .= '->' . strval($nums[$i-1]);
            }
            $ret[] = $item;
        }

        return $ret;
    }
}