数字在排序数组中出现的次数(Java)

思路:

 * 1、二分查找法查找到数字出现的最左侧位置
 * 2、二分查找法查找到数字出现的最右侧位置
 * 3、计算出现的次数

代码:

package com.my.test.datastructure.array;

/**
 * 数字在排序数组中出现的次数
 * 
 * 思路:
 * 1、二分查找法查找到数字出现的最左侧位置
 * 2、二分查找法查找到数字出现的最右侧位置
 * 3、计算出现的次数
 */
public class NumCountInSortedArray
{
    
    public static int numCountInSortedArray(int[] arr, int num) {
        if (arr == null || arr.length == 0) {
            return 0;
        }
        
        int len = arr.length;
        int numStartIndex = getFirstNumIndex(arr, num, 0, len - 1);
        int numLastIndex = getLastNumIndex(arr, num, 0, len - 1);
        
        if (numStartIndex >= 0 && numLastIndex >= numStartIndex) {
            return numLastIndex - numStartIndex + 1;
        }
        
        return 0;
    }
    
    private static int getFirstNumIndex(int[] arr, int num, int startIndex, int endIndex) {
        // 判断非法条件
        if (arr == null || arr.length < 1 || startIndex < 0 || endIndex < 0 || startIndex > endIndex) {
            return -1;
        }
        
        // 在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方
        // 右移一位相当于除2,右移n位相当于除以2的n次方
        int midIndex = (startIndex + endIndex) >> 1;
        
        int curFoundNum = arr[midIndex];
        // 找到了num对应的首个索引
        if (curFoundNum == num ) {
            if (midIndex == 0 || (midIndex > 0 && arr[midIndex - 1] < curFoundNum)) {
                return midIndex;
            }
        } 
        // 没有找到
        int newStartIndex = startIndex;
        int newEndIndex = endIndex;
        
        // 目标数据在右侧
        if (curFoundNum < num) {
            newStartIndex = midIndex + 1;
        // 目标数据在左侧, 相等情况去左侧找         
        } else {
            newEndIndex = midIndex - 1;
        }
        
        // 重新查找下一区间
        return getFirstNumIndex(arr, num, newStartIndex, newEndIndex);
    }

    private static int getLastNumIndex(int[] arr, int num, int startIndex, int endIndex) {
        if (null == arr || arr.length < 1 || startIndex < 0 || endIndex < 0 || startIndex > endIndex) {
            return -1;
        }
        
        int midIndex = (startIndex + endIndex) >> 1;
        
        int curFoundNum = arr[midIndex];
        
        // 找到了
        if (curFoundNum == num) {
            if (midIndex == arr.length - 1 || (midIndex < arr.length - 1 && arr[midIndex + 1] > curFoundNum)) {
                return midIndex;
            }
        }
        
        // 没有找到
        int newStartIndex = startIndex;
        int newEndIndex = endIndex;
        
        // 相等情况去右侧找
        // 目标数据在右侧
        if (curFoundNum <= num) {
            newStartIndex = midIndex + 1;
        } else {
            newEndIndex = midIndex - 1;
        }
        
        return getLastNumIndex(arr, num, newStartIndex, newEndIndex);
    }
    
    public static void main(String[] args)
    {
        int[] arr = {1,1,2,2,2,2};
        System.out.println(numCountInSortedArray(arr, 2));
    }

}

猜你喜欢

转载自blog.csdn.net/zangdaiyang1991/article/details/88716570