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

126 阅读1分钟

思路

按照二分查找的思想,分别查找该数字第一次出现的位置和最后一次出现的位置。

while(i <= j) 退出后,有 left>right,关键在于处理好边界。

写法二

直接不叼退出后的jb事

public class Solution {
    public int[] searchRange(int[] nums, int target) {
        int len = nums.length;
        if (len == 0) {
            return new int[]{-1, -1};
        }
        return new int[]{findFirst(nums, target), findLast(nums, target)};
    }
    //找第一次出现的位置
    public int findFirst(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        int index = -1;
        while (left <= right) {
            int mid = left + (right - left) / 2;//防止大数相加溢出
            if (nums[mid] == target) {
                right = mid - 1; // 这里一定要-1,否则找到target时left= right = mid会卡住
                index = mid;
            } else if (nums[mid] > target) {
                right = mid - 1;
            } else if (nums[mid] < target) {
                left = mid + 1;
            }
        }
        return index;
    }
    //找最后一次出现的位置
    public int findLast(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        int index = -1;
        while (left <= right) {
            int mid = left + (right - left) / 2;//防止大数相加溢出
            if (nums[mid] == target) {
                left = mid + 1;// 这里一定要+1,否则找到target时left= right = mid会卡住
                index = mid;
            } else if (nums[mid] > target) {
                right = mid - 1;
            } else if (nums[mid] < target) {
                left = mid + 1;
            }
        }
        return index;
    }
}

写法一

public class Solution {
    public int[] searchRange(int[] nums, int target) {
        int len = nums.length;
        if (len == 0) {
            return new int[]{-1, -1};
        }
        return new int[]{findFirst(nums, target), findLast(nums, target)};
    }
    //找第一次出现的位置
    public int findFirst(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;//防止大数相加溢出
            if (nums[mid] == target) {
                right = mid - 1;
            } else if (nums[mid] > target) {
                right = mid - 1;
            } else if (nums[mid] < target) {
                left = mid + 1;
            }
        }
        //没找到
        if (left == nums.length || nums[left] != target) {//left == nums.length对应left越出上界的情况
            return -1;
        }
        // if (nums[left] == target)
        return left;
        
    }
    //找最后一次出现的位置
    public int findLast(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;//防止大数相加溢出
            if (nums[mid] == target) {
                left = mid + 1;
            } else if (nums[mid] > target) {
                right = mid - 1;
            } else if (nums[mid] < target) {
                left = mid + 1;
            }
        }
        //没找到
        if (right == -1 || nums[right] != target) {//right == -1对应right越出下界的情况
            return -1;
        }
        // if (nums[right] == target)
        return right;
    }
}