数字在排序数组中的位置

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

  在排序数组中查找一个数,这明显就需要利用二分法。不过现在需要在数组中找某个数出现的次数,那么我们就需要找到这个数字在数组中第一次出现的位置,以及最后一次出现的位置,将这两个下标一减再加上1就是我们需要的结果。

  找第一次出现的位置时,我们利用二分法找到了目标值,它的下标为i,此时还不能停止寻找,我们得判断一下 i - 1 位置上的数是否也是目标值,如果是,那么就继续二分的过程,如果不是,那么我们就找到了这个第一次出现的位置。

  找最后一次出现的位置也是同理,找到目标值后,再判断一下i + 1位置的数是否也是目标值,然后决定是否继续二分。

  代码如下:

import org.junit.Test;

public class Solution1 {
    public int findFirst(int[] array, int target, int start, int end) {
        if (start > end) {
            return -1;
        }
        int mid = (start + end) / 2;
        int num = array[mid];
        if (num == target) {
            if ((mid > 0 && array[mid - 1] != target) || mid == 0) {
                return mid;
            } else {
                end = mid - 1;
            }
        } else if (num > target) {
            end = mid - 1;
        } else {
            start = mid + 1;
        }
        return findFirst(array, target, start, end);
    }

    // 这里也是给自己一个警示吧,以后写参数列表的时候,越重要的参数,越要往前放,这样出错的概率机会低
    public int findLast(int[] array, int target, int start, int end, int length) {
        if (start > end) {
            return -1;
        }
        int mid = (start + end) / 2;
        int num = array[mid];
        if (num == target) {
            if ((mid < length - 1 && array[mid + 1] != target) || mid == length - 1) {
                return mid;
            } else {
                start = mid + 1;
            }
        } else if (num < target) {
            start = mid + 1;
        } else {
            end = mid - 1;
        }
        return findLast(array, target, start, end, length);
    }

    public int GetNumberOfK(int[] array, int k) {
        if (array == null) {
            return -1;
        }
        int len = array.length;
        int first = findFirst(array, k, 0, len - 1);
        // start 和 end 是二分的时候的数组下标,取值范围就是(0, len - 1);而length是数组的长度,范围是(1, len)
        int last = findLast(array, k, 0, len - 1, len);
        int result = 0;
        // 考虑目标不在数组中的情况
        if (first != -1 && last != -1) {
            result = last - first + 1;
        }
        return result;
    }
    @Test
    public void test() {
        int[] arr = {1, 1, 2, 2, 3, 5, 5, 9, 9};
        int k = 9;
        int result = GetNumberOfK(arr, k);
        System.out.println(result);
    }
}

















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值