[LeetCode No.34] 在排序数组中查找元素的第一个和最后一个位置

题目

题解

题解一:
最简单的解法就是暴力解法
直接遍历nums数组。当第一次出现target时,保存其下标。最后一次出现target时。保存下标。 时间复杂度为O(n)

public class Solution {
    public static int[] searchRange(int[] nums, int target) {
        int [] answer = {-1,-1};
        for (int i = 0 ;i < nums.length ;i++){
            if(nums[i] == target){
                answer[0] = i;
                answer[1] = i;
                for (int j = i+1;j < nums.length;j++){
                    if (nums[j] == target)
                        answer[1] = j;
                }
                break;
            }
        }
        return answer;
    }
}

题解二:
进阶要求时间复杂度为O(log n),又已知nums数组为排序数组,那么显然使用二分查找法。
1.先看数组长度,若未0,直接返回{-1,-1}
2.查找target第一次出现的位置。若未找到则返回{-1,-1}
3.找target最后出现的位置。此处不存在未找到情况,因为第二步已经确定target是否在数组中存在

public class Solution2_self {
    public static int[] searchRange(int[] nums, int target) {
        int length = nums.length;

        if (length == 0)                //若数组长度为0
            return new int[]{-1,-1};

        int start = FindStart(nums,target);       //找target第一次出现的位置
        if (start == -1){                            //若没有第一次出现
            return new int[]{-1,-1};
        }
        int last = FindLast(nums,target);               //找target最后出现的位置
        return new int[]{start,last};
    }

    public static int FindStart(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;

        while (left<right){
            int mid = left+(right-left)/2;      //mid左取整还是右取整,要考虑只有最后只有两个数时。即else的情况来确定 
            if (nums[mid]>target){                                                      //否则陷入死循环
                right = mid - 1;
            }
            else if (nums[mid]<target){
                left = mid + 1;
            }else {
                right = mid;
            }
        }

        if (nums[left] != target)                           //若最终找到的数,不是targer。则数组没有target数
            return -1;
        return left;
    }


    public static int FindLast(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        while (left<right){
            int mid = left+(right-left+1)/2;
            if (nums[mid] > target){
                right = mid - 1;
            }else if (nums[mid] < target){
                left = mid + 1;
            }else {
                left = mid;
            }
        }
        return left;
    }
}
原文地址:https://www.cnblogs.com/Mr-BING/p/14083604.html