Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

汇总区间 #166

Open
yankewei opened this issue Aug 26, 2023 · 1 comment
Open

汇总区间 #166

yankewei opened this issue Aug 26, 2023 · 1 comment
Labels
数组 题目类型为数组 简单 题目难度为简单

Comments

@yankewei
Copy link
Owner

给定一个 无重复元素 的 有序 整数数组 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"

提示:

  • 0 <= nums.length <= 20
  • -231 <= nums[i] <= 231 - 1
  • nums 中的所有值都 互不相同
  • nums 按升序排列
@yankewei yankewei added 简单 题目难度为简单 数组 题目类型为数组 labels Aug 26, 2023
@yankewei
Copy link
Owner Author

yankewei commented Aug 26, 2023

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

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;
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
数组 题目类型为数组 简单 题目难度为简单
Projects
None yet
Development

No branches or pull requests

1 participant