12

PHP 求解在排序数组中查找元素的第一个和最后一个位置

 3 years ago
source link: https://hxd.life/2020/12/02/PHP-求解在排序数组中查找元素的第一个和最后一个位置/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在排序数组中查找元素的第一个和最后一个位置

给定一个按照升序排列的整数数组 nums ,和一个目标值 target 。找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target ,返回  [-1, -1]

进阶:

  • 你可以设计并实现时间复杂度为  O(log n)  的算法解决此问题吗?  

示例 1:

输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]

示例 2:

输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]

示例 3:

输入:nums = [], target = 0
输出:[-1,-1]

提示:

  • 0 <= nums.length <= 105
  • -109 <= nums[i] <= 109
  • nums 是一个非递减数组
  • -109 <= target <= 109

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路 1

暴力查找加处理特殊结果

class Solution {

    /**
     * @param Integer[] $nums
     * @param Integer $target
     * @return Integer[]
     */
    function searchRange($nums, $target) {
        // 设置默认值 

        $result = [-1, -1];

        if (empty($nums)) {
            return $result;
        }

        // 循环 + 暴力赋值 $result

        $i = 0;
        foreach ($nums as $key => $num) {
            if ($num == $target) {
                if ($i == 0) {
                    $result[0] = $key;
                } else {
                    $result[1] = $key;
                }
                $i++;
            }
        }

        // 兼容只出现一次的情况

        if ($result[0] !== -1 && $result[1] == -1) {
            return [$result[0], $result[0]];
        }

        return $result;
    }
}

解题思路 2

利用二分法思路,先利用二分法找到符合 target 的值,再分别用二分法求 target 起始的位置和结束的位置。

class Solution {

    /**
     * @param Integer[] $nums
     * @param Integer $target
     * @return Integer[]
     */
    function searchRange($nums, $target) {
        $result = [-1, -1];
        if (empty($nums)) {
            return $result;
        }

        $left = 0;
        $count = count($nums);
        $right = $count - 1;
        while ($left <= $right) {
            $mid = round($left + ($right - $left) / 2);
            if ($nums[$mid] == $target) {
                $left = $mid;
                $right = $mid;
                // 如果 $nums[$left - 1] == $nums[$left],则继续二分法找起始位置

                while ($left > 0 && $nums[$left - 1] === $nums[$left]) {
                    --$left;
                }

                // 如果 $nums[$right + 1] == $nums[$right],则继续二分法找结束位置

                while ($right < $count - 1 && $nums[$right] === $nums[$right + 1]) {
                    ++$right;
                }

                $result[0] = $left;
                $result[1] = $right;
                break;
            } else if ($nums[$mid] > $target) {
                $right = $mid - 1;
            } else {
                $left = $mid + 1;
            }
        }

        return $result;
    }
}

参考链接:

  1. 极客时间 算法面试通关40讲

最后恰饭 阿里云全系列产品/短信包特惠购买 中小企业上云最佳选择 阿里云内部优惠券


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK