53 在排序数组中查找数字

53-1 数字在有序数组中出现的次数

统计一个数字在排序数组中出现的次数。

// 二分查找到中间target的位置,然后往左右延伸
class Solution {
    public int search(int[] nums, int target) {
        if(nums == null || nums.length == 0) return 0;
        int n = nums.length;
        int l = 0;
        int r = n-1;
        int mid = 0;
        while(l<=r){
            mid = l + (r-l)/2;
            if(target > nums[mid]) l=mid + 1;
            else if(target < nums[mid]) r = mid - 1;
            else break;
        }
        int ans = 0;
        for(int i = mid;i<n;i++) if(nums[i] == target) ans++;
        for(int i = mid;i>=0;i--) if(nums[i] == target) ans++;
        return ans==0?0:ans-1;

    }

}
// 二分查找到目标数字的起始位置与结束位置
class Solution {
    public int search(int[] nums, int target) {
        if(nums == null || nums.length == 0) return 0;
        if(getFirstK(nums,target) == -1 || getLastK(nums,target) == -1) return 0;
        int start = getFirstK(nums,target);
        int end = getLastK(nums,target);
        return end - start+1;

    }
    public int getFirstK(int[] nums,int target){
        int n = nums.length;
        int l =0;
        int r = n-1;
        int mid = 0;
        while(l<=r){
            mid = l + (r-l)/2;
            if(nums[mid] > target){r = mid-1;}
            else if(nums[mid]<target){l=mid+1;}
            else{
                if(mid > 0 && nums[mid-1] != target || mid == 0) return mid;
                else r=mid-1;
            }
        }
        return -1;
    }
    public int getLastK(int[] nums,int target){
        int n = nums.length;
        int l = 0;
        int r = n-1;
        int mid = 0;
        while(l<=r){
            mid = l + (r-l)/2;
            if(nums[mid] > target){r = mid-1;}
            else if(nums[mid]<target){l=mid+1;}
            else{
                if(mid<n-1 && nums[mid+1] != target || mid == n-1) return mid;
                else l = mid+1;
            }
        }
        return -1;
    }
}

0~n-1中缺失的数字(数组有序)

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

// 利用等差数列的求和公式
class Solution {
    public int missingNumber(int[] nums) {
        if(nums == null) return -1;
        int n = nums.length;
        int sum = 0;
        int s = (0+n)*(n+1)/2;
        for(int num:nums) sum+=num;
        System.out.println(s + " " + sum);
        return s-sum;
    }
}
// 目标转化成为找到第一个值与下标不相等的位置
// 直接暴力遍历
class Solution {
    public int missingNumber(int[] nums) {
        if(nums == null) return 0;
        int n = nums.length;
        for(int i = 0;i<n;i++) if(i != nums[i]) return i;
        return n; 
    }
} 
// 目标转化成为找到第一个值与下标不相等的位置
// 利用二分进行优化,因为自从一个不相等之后之后的都会错位
class Solution {
    public int missingNumber(int[] nums) {
        if(nums == null) return -1;
        int n = nums.length;
        int l = 0;
        int r = n-1;
        int mid = 0;
        while(l<=r){
            mid = l+(r-l)/2;
            if(mid != nums[mid]){
                if(mid == 0 || nums[mid-1] == mid -1) return mid;
                r = mid-1;
            }else{
                l = mid+1;
            }
        }
        if(l == n) return n;
        return -1;

    }
}

数组中数值和下标相等的元素(数组有序)

class Solution{
    public int findEqualNumber(int[] nums){
        if(nums == null) return -1;
        int n = nums.length;
        int l = 0;
        int r = n-1;
        int mid = 0;
        while(l<=r){
            mid = l + (r-l)/2;
            if(nums[mid] == mid) return mid;
            else if(nums[mid] > mid) r = mid-1;
            else l = mid + 1;

        }
        return -1;
    }
}
posted @ 2021-06-21 11:06  BOTAK  阅读(56)  评论(0编辑  收藏  举报