1
+ # 面试题53 - I. 在排序数组中查找数字 I
2
+
3
+ > 本文首发于公众号「图解面试算法」,是 [图解 LeetCode ](<https://github.com/MisterBooo/LeetCodeAnimation>) 系列文章之一。
4
+ >
5
+ > 同步博客:https://www.algomooc.com
6
+
7
+ 题目来源于 LeetCode 上 面试题53 - I. 在排序数组中查找数字 I. 是算法入门的一道题。
8
+
9
+ ## 题目
10
+
11
+ 统计一个数字在排序数组中出现的次数。
12
+
13
+
14
+ 示例 1:
15
+
16
+ ```
17
+ 输入: nums = [5,7,7,8,8,10], target = 8
18
+ 输出: 2
19
+ ```
20
+
21
+ 示例 2:
22
+
23
+
24
+ ```
25
+ 输入: nums = [5,7,7,8,8,10], target = 6
26
+ 输出: 0
27
+ ```
28
+
29
+
30
+ 限制:
31
+
32
+ ```
33
+ 0 <= 数组长度 <= 50000
34
+ ```
35
+ ## 题目解析
36
+
37
+ 题目很好理解,就是要找到给定的target在排序数组中出现的次数,刚接触到算法的萌新,不仔细审题的话,会忽略排序这个重要的点。然后直接暴力循环数组,定义一个计数变量count,每次出现目标值,count加一,遍历结束,return count。
38
+
39
+ 老司机一看到这个题,“排序”,因为数组是排序的,所以所以目标都会连在一起,我们只要找到目标值左右边界,然后相减加一就可以得到出现的次数。
40
+
41
+ 要找到左右边界,其实可以理解为在数组中找到某个值,那么就会想到最常见的一个算法,二分法。
42
+
43
+ 1. 定义两个指针:start,end分别指向数组的头和尾部
44
+ 2. 定义mid等于Math.ceil((start+end)/2)
45
+ 3. 判断mid指向的数组的元素和目标值target的大小
46
+ 4. mid大,那么移动end,否则移动start
47
+ 5. 重复以上的操作两遍,分别得到左边界left,右边界right
48
+ 6. 最后得到目标值出现次数 right - left + 1
49
+
50
+
51
+ ## 动画理解
52
+
53
+
54
+ <video id="video" controls="" preload="none" >
55
+ <source id="mp4" src="../Animation/Interview053-I- Find-Number-In-Sort-Array-I.mp4" type="video/mp4">
56
+ </video>
57
+
58
+ ## 参考代码
59
+
60
+
61
+ ```javaScript
62
+ /**
63
+ * @param {number[]} nums
64
+ * @param {number} target
65
+ * @return {number}
66
+ */
67
+ var search = function(nums, target) {
68
+ let start = 0;
69
+ let mid = 0;
70
+ let end = nums.length - 1;
71
+ let left = 0;
72
+ let right = 0;
73
+ // 查找右边界
74
+ while(start <= end) {
75
+ mid = Math.ceil((start + end) / 2)
76
+ if (nums[mid] <= target) {
77
+ start = mid + 1
78
+ } else {
79
+ end = mid -1
80
+ }
81
+ }
82
+ right = start - 1; // 右边界
83
+ // 查找左边界
84
+ start = 0;
85
+ mid = 0;
86
+ end = nums.length - 1;
87
+ while(start <= end) {
88
+ mid = Math.ceil((start + end) / 2)
89
+ if (nums[mid] < target) {
90
+ start = mid + 1
91
+ } else {
92
+ end = mid -1
93
+ }
94
+ }
95
+ left = end + 1
96
+ return right - left + 1
97
+ };
98
+ ```
99
+
100
+ ## 复杂度分析
101
+
102
+ 二分查找的时间复杂度计算如下:假设一个数组长度为n,每次查找后数据长度减半,第一次查找后数据长度为n/2,第二次查找后数据长度为n/(2的2次方),第k次查找后数据长度为n/(2的k次方),最坏情况下数数据长度为1时找到该数,即n/(2的k次方)=1, 解得k=log2(N).
103
+
104
+ 时间复杂度为:O(log2n)。
105
+
106
+ 
0 commit comments