据说是微软的一道题。
题目:在排序数组中,找出给定数字的出现次数,比如 [1, 2, 2, 2, 3] 中2的出现次数是3次。
算法的思想,使用修改后的二分查找法,找到最左边 2 的下标为 1 ,最后边 2 的下标为 3,然后返回3 – 1 + 1 = 3 即可,算法复杂度为 logN。
编码的时候,用一个变量 last 来存储本次查找到的位置,然后根据情况变换查找方向,就可以分别确定 left 和 right 下标的值。
代码实现:
view sourceprint?01 package org.leeing.interview;
02
03 /**
04 * 题目:在排序数组中,找出给定数字的出现次数,比如 [1, 2, 2, 2, 3]
05 * 2 的出现次数是3次。
06 *
07 * @author leeing
08 *
09 */
10 public class NumberCounter {
11 public static void main(String[] args) {
12 int a[] = { 1, 2, 2, 2, 2, 3, 4 };
13 int counter = numbercounter(a, 4);
14 System.out.println(counter);
15 }
16
17 static int numbercounter(int[] a, int num) {
18 int left = binarysearch(a, num, true);
19 int right = binarysearch(a, num, false);
20 System.out.println("left is :" + left);
21 System.out.println("right is :" + right);
22
23 if (left != -1 && right != -1) {
24 return right - left + 1;
25 } else {
26 return 0;
27 }
28 }
29
30 static int binarysearch(int[] a, int target, boolean isLeft) {
31 int left = 0, right = a.length - 1;
32 int last = 0;
33 while (left <= right) {
34 int mid = (left + right) / 2;
35 if (a[mid] < target) {
36 left = mid + 1;
37 } else if (a[mid] > target) {
38 right = mid - 1;
39 } else {
40 last = mid;
41
42 if (isLeft) {
43 right = mid - 1;
44 } else {
45 left = mid + 1;
46 }
47 }
48 }
49 return last > 0 ? last : -1;
50 }
51 }
|