数字在排序数组中出现的次数
Posted Tongkey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数字在排序数组中出现的次数相关的知识,希望对你有一定的参考价值。
题目:统计一个数字在排序数组中出现的次数。例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出4。
暴力解法的时间复杂度为O(n),还有更优的解法,运用二分查找,时间复杂度为O(logn):
1.先找出第一次出现的下标值,设left,mid,right分别代表数组的起始,中间,结束的下标。
若数组中间的数a[mid]大于k,则right = mid -1;
若数组中间的数a[mid]小于k,则left = mid+1;
若数组中间的数a[mid]等于k,判断a[mid-1] 是否等于k,若不等于,说明是第一次出现的下标,返回mid下标;若等于,则说明第一次出现的下标还在mid的左边,right = mid -1;
递归重复以上过程。
2.再找出最后出现的下标,原理同上。
参考代码:
package test; import org.junit.Test; public class Solution { public int getNumOfK(int[] a, int k) { if (a == null || a.length == 0) return 0; int first = getFirstK(a, 0, a.length - 1, k); int last = getLastK(a, 0, a.length - 1, k); if (first > -1 && last > -1) return last - first + 1; return 0; } private int getFirstK(int[] a, int left, int right, int k) { if (left > right) return -1; int mid = (left + right) / 2; int midData = a[mid]; // 中间的数等于k if (midData == k) { //mid的前一个数不是k,说明是第一个出现的数 if (mid > 0 && a[mid - 1] != k || mid == 0) return mid; else //不是第一个出现的数,第一个出现的数再数组的左边 right = mid - 1; // 中间的数大于k,说明在数组的左边 } else if (midData > k) right = mid - 1; else // 中间的数小于k,说明在数组的右边 left = mid + 1; return getFirstK(a, left, right, k); } private int getLastK(int[] a, int left, int right, int k) { if (left > right) return -1; int mid = (left + right) / 2; int midData = a[mid]; if (midData == k) { if (mid < a.length - 1 && a[mid + 1] != k || mid == a.length - 1) return mid; else left = mid + 1; } else if (midData > k) right = mid - 1; else left = mid + 1; return getLastK(a, left, right, k); } @Test public void testSolution() { int[] a = { 1, 2, 3, 3, 3, 3, 4, 5 }; int k = 3; System.out.println(getNumOfK(a, k));//4 } }
以上是关于数字在排序数组中出现的次数的主要内容,如果未能解决你的问题,请参考以下文章