剑指offer-38.数字在排序数组中出现的次数

https://www.nowcoder.com/practice/70610bf967994b22bb1c26f9ae901fa2?tpId=13&tqId=11190&tPage=2&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking

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

方法一:
扫描一遍数组,统计相应数字出现的次数。
时间复杂度为 O(n)

方法二:
时间复杂度为 O(logn)
数组是有序的,要想到使用二分查找的思路。
分别找到给定数字在数组中出现的第一个位置,和最后一个位置,相减+1,即得到个数。
找第一个位置和最后一个位置,在二分查找的基础上修改。

public class Solution {
    public int GetNumberOfK(int[] array, int k) {
        if (array == null || array.length == 0) {
            return 0;
        }
        int firstPos = GetFirstK(array, k, 0, array.length - 1);
        int lastPos = GetLastK(array, k, 0, array.length - 1);
        if (firstPos > -1 && lastPos > -1) {
            return lastPos - firstPos + 1;
        } else {
            return 0;
        }
    }

    private int GetFirstK(int[] array, int k, int start, int end) {
        while (start <= end) {
            int middleIndex = (start + end) / 2;
            if (array[middleIndex] == k) {
                if (middleIndex > 0 && array[middleIndex - 1] != k || middleIndex == 0) {
                    return middleIndex;
                } else {
                    end = middleIndex - 1;
                }
            } else if (array[middleIndex] > k) {
                end = middleIndex - 1;
            } else {
                start = middleIndex + 1;
            }
        }
        return -1;
    }

    private int GetLastK(int[] array, int k, int start, int end) {
        while (start <= end) {
            int middleIndex = (start + end) / 2;
            if (array[middleIndex] == k) {
                if (middleIndex < (array.length - 1) && array[middleIndex + 1] != k || middleIndex == array.length - 1) {
                    return middleIndex;
                } else {
                    start = middleIndex + 1;
                }
            } else if (array[middleIndex] > k) {
                end = middleIndex - 1;
            } else {
                start = middleIndex + 1;
            }
        }
        return -1;
    }
}

方法三:

如果 array数组中都是整数,可以稍微变一下,不是搜索k的两个位置,而是搜索 k-0.5 和 k+0.5 这两个数应该插入的位置,然后相减即可。

class Solution {
    public int GetNumberOfK(int[] array, int k) {
        if (array == null || array.length == 0) {
            return 0;
        }
        return GetPosition(array, k + 0.5, 0, array.length - 1) - GetPosition(array, k - 0.5, 0, array.length - 1);
    }

    private int GetPosition(int[] array, double k, int start, int end) {
        while (start <= end) {
            int middleIndex = (start + end) / 2;
            if (array[middleIndex] > k) {
                end = middleIndex - 1;
            } else {
                start = middleIndex + 1;
            }
        }
        return start;//start为最终要插的位置
    }
}

你可能感兴趣的:(剑指offer,剑指offer题解)