《剑指offer》——数字在排序数组中出现的次数

更多2019年的技术文章,欢迎关注我的微信公众号:码不停蹄的小鼠松(微信号:busy_squirrel),也可扫下方二维码关注获取最新文章哦~

《剑指offer》——数字在排序数组中出现的次数_第1张图片

文章目录

  • 非二分查找
  • 二分查找

T:

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

先来说说这道题的用时判断,真的是不太一样啊,非二分查找比二分查找的用时还短,只能说明是出题者给出的测试用例的问题。

非二分查找

如果不用二分查找,其复杂度均为 O ( n ) O(n) O(n)

一般的有两种方式:

  1. 可以从前往后遍历,先碰到一个为k的,然后找下一个不是为k的下标;
  2. 从两端开始遍历,即分别找k元素的两端,然后相减。

这两种方式,其方式都差不多,再怎么折腾,时间复杂度还是在 O ( n ) O(n) O(n)

给出code:

	/**
	 * T: 数字在排序数组中出现的次数
	 *
	 * 题目描述
	 * 统计一个数字在排序数组中出现的次数。
	 *
	 * date: 2015.11.22 10:57
	 * @author SSS
	 *
	 */
	public class Solution {
	    /**
	     * 最简单的,从前往后扫描,找到第一个出现的地方,
	     * 然后往后遍历,直到后一个元素不等于k,然后break;
	     * @param array
	     * @param k
	     * @return
	     */
	    public int GetNumberOfK(int [] array , int k) {
	        int count = 0;
	        int index = 0;
	         
	        for (int i = 0; i < array.length; i++) {
	            if (array[i] == k) {
	                index = i;
	                break;
	            }
	        }
	         
	        for (int i = index; i < array.length; i++) {
	            if (array[i] == k) {
	                count ++;
	            } else {
	                break;
	            }
	        }
	         
	        return count;
	    }
	}

二分查找

这是比较常用的搜索方法,时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)

但这种方法的使用有一个前提,就是待检查数组必须是有序的。

code:

	/**
	 * T: 数字在排序数组中出现的次数
	 *
	 * 题目描述
	 * 统计一个数字在排序数组中出现的次数。
	 *
	 * date: 2015.11.22 14:43
	 * @author SSS
	 *
	 */
	public class Solution {
	    public int GetNumberOfK(int [] array , int k) {
	       int count = 0;
	        // 找到数组array中元素k的下标位置
	        int index = this.binarySearch(array, 0, array.length - 1, k);
	        // 没找到就返回0
	        if (index == -1) {
	            return count;
	        }
	         
	        // 从下标往前开始扫描还有多少个k
	        int beforeIndex = 0;
	        for (beforeIndex = index - 1; beforeIndex > -1; beforeIndex--) {
	            if (array[beforeIndex] != k) {
	                break;
	            }
	        }
	        // 从下标往后开始扫描还有多少个k
	        int afterIndex = 0;
	        for (afterIndex = index + 1; afterIndex < array.length; afterIndex++) {
	            if (array[afterIndex] != k) {
	                break;
	            }
	        }
	        // 相减
	        count = afterIndex - beforeIndex - 1;
	         
	        return count;
	    }
	     
	    /**
	     * 二分查找
	     *
	     * 函数功能:
	     * 在下标start和end之间,找到其中间位置,如果该中间位置所在的元素
	     * 的值为k,那么就返回该元素的下标;否则,
	     * 判断该元素是比k大还是比k小,然后在对应的区间内再作搜寻。
	     * 最终直到找出所在下标,或者start已经比end大的情况,就终止。
	     *
	     * @param array
	     * @param start
	     * @param end
	     * @param k
	     * @return
	     */
	    public int binarySearch(int []array, int start, int end, int k) {
	        // 这种情况下,说明没有找到
	        if (start > end) {
	            return -1;
	        }
	        int mid = (start + end) / 2;
	        if (array[mid] == k) {
	            return mid;
	        }
	         
	        if (array[mid] > k) {
	            return binarySearch(array, start, mid - 1, k);
	        } else {
	            return binarySearch(array, mid + 1, end, k);
	        }
	    }
	}

更多2019年的技术文章,欢迎关注我的微信公众号:码不停蹄的小鼠松(微信号:busy_squirrel),也可扫下方二维码关注获取最新文章哦~

《剑指offer》——数字在排序数组中出现的次数_第2张图片

你可能感兴趣的:(算法,java)