mirror of
https://gitee.com/TheAlgorithms/LeetCodeAnimation.git
synced 2024-12-06 15:19:44 +08:00
fix: fix Interview053 format
This commit is contained in:
parent
06c488ea78
commit
fbb3449033
@ -1,153 +0,0 @@
|
||||
# 面试题53 - I. 在排序数组中查找数字 I
|
||||
|
||||
> 本文首发于公众号「图解面试算法」,是 [图解 LeetCode ](<https://github.com/MisterBooo/LeetCodeAnimation>) 系列文章之一。
|
||||
>
|
||||
> 同步博客:https://www.algomooc.com
|
||||
|
||||
题目来源于 LeetCode 上 面试题53 - I. 在排序数组中查找数字 I. 是算法入门的一道题。
|
||||
|
||||
## 题目
|
||||
|
||||
统计一个数字在排序数组中出现的次数。
|
||||
|
||||
|
||||
示例 1:
|
||||
|
||||
```
|
||||
输入: nums = [5,7,7,8,8,10], target = 8
|
||||
输出: 2
|
||||
```
|
||||
|
||||
示例 2:
|
||||
|
||||
|
||||
```
|
||||
输入: nums = [5,7,7,8,8,10], target = 6
|
||||
输出: 0
|
||||
```
|
||||
|
||||
|
||||
限制:
|
||||
|
||||
```
|
||||
0 <= 数组长度 <= 50000
|
||||
```
|
||||
|
||||
|
||||
## 思路解析
|
||||
|
||||
### 暴力循环法
|
||||
|
||||
题目看上去是很简单,就是找到一个目标数字在数组中出现的次数,不管数组是有序还是无序的,我们都可以用的一种方法就是暴力循环法
|
||||
|
||||
#### 思路
|
||||
|
||||
定义一个count来记录目标值出现的次数,初始值为0,然后遍历这个数组,然后如果当前值和目标值target一致,那么count就加一,最后return count。这种解法的时间复杂度是O(N)
|
||||
|
||||
#### 代码实现
|
||||
|
||||
|
||||
```javaScript
|
||||
/**
|
||||
* @param {number[]} nums
|
||||
* @param {number} target
|
||||
* @return {number}
|
||||
*/
|
||||
var search = function(nums, target) {
|
||||
let count = 0;
|
||||
for(let i of nums) {
|
||||
if (i === target) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
};
|
||||
```
|
||||
|
||||
### 改良的暴力循环
|
||||
|
||||
#### 思路
|
||||
|
||||
因为数组已排序了,所以我们其实可以不用遍历全部,用双指针分别从头部和尾部开始同时遍历,然后找到目标值的左右边界的位置,然后通过计算得到count。其实就是比全部遍历少了目标值出现的次数,它的算法复杂度还是O(n)
|
||||
|
||||
count = 右边界的index - 左边界的index + 1
|
||||
|
||||
#### 代码实现
|
||||
|
||||
|
||||
```javaScript
|
||||
/**
|
||||
* @param {number[]} nums
|
||||
* @param {number} target
|
||||
* @return {number}
|
||||
*/
|
||||
var search = function(nums, target) {
|
||||
let [left, right] = [0, nums.length - 1]
|
||||
while(left <= right && (nums[left] !== target || nums[right] !== target)) {
|
||||
if (left === right && nums[left] !== target) {
|
||||
return 0;
|
||||
}else if (nums[left] !== target) {
|
||||
left++;
|
||||
}else if (nums[right] !== target){
|
||||
right--;
|
||||
}
|
||||
}
|
||||
return right - left + 1;
|
||||
};
|
||||
```
|
||||
|
||||
### 二分法
|
||||
|
||||
#### 思路
|
||||
|
||||
除了遍历,我们在排序数组中查找值还可以用的一种方法是二分法,思路还是和改良的暴力循环法一样,先找到左右边界,然后做计算。时间复杂度为O(logn)
|
||||
|
||||
#### 代码实现
|
||||
|
||||
```javaScript
|
||||
/**
|
||||
* @param {number[]} nums
|
||||
* @param {number} target
|
||||
* @return {number}
|
||||
*/
|
||||
var search = function(nums, target) {
|
||||
let start = 0;
|
||||
let mid = 0;
|
||||
let end = nums.length - 1;
|
||||
let left = 0;
|
||||
let right = 0;
|
||||
// 查找右边界
|
||||
while(start <= end) {
|
||||
mid = Math.ceil((start + end) / 2)
|
||||
if (nums[mid] <= target) {
|
||||
start = mid + 1
|
||||
} else {
|
||||
end = mid -1
|
||||
}
|
||||
}
|
||||
right = start - 1; // 右边界
|
||||
// 查找左边界
|
||||
start = 0;
|
||||
mid = 0;
|
||||
end = nums.length - 1;
|
||||
while(start <= end) {
|
||||
mid = Math.ceil((start + end) / 2)
|
||||
if (nums[mid] < target) {
|
||||
start = mid + 1
|
||||
} else {
|
||||
end = mid -1
|
||||
}
|
||||
}
|
||||
left = end + 1
|
||||
return right - left + 1
|
||||
};
|
||||
```
|
||||
|
||||
## 动画理解
|
||||
|
||||
|
||||
<video id="video" controls="" preload="none" >
|
||||
<source id="mp4" src="../animation/Interview Question 53 - I. Find number in sort arrayI.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
![](../../Pictures/qrcode.jpg)
|
@ -0,0 +1,106 @@
|
||||
# 面试题53 - I. 在排序数组中查找数字 I
|
||||
|
||||
> 本文首发于公众号「图解面试算法」,是 [图解 LeetCode ](<https://github.com/MisterBooo/LeetCodeAnimation>) 系列文章之一。
|
||||
>
|
||||
> 同步博客:https://www.algomooc.com
|
||||
|
||||
题目来源于 LeetCode 上 面试题53 - I. 在排序数组中查找数字 I. 是算法入门的一道题。
|
||||
|
||||
## 题目
|
||||
|
||||
统计一个数字在排序数组中出现的次数。
|
||||
|
||||
|
||||
示例 1:
|
||||
|
||||
```
|
||||
输入: nums = [5,7,7,8,8,10], target = 8
|
||||
输出: 2
|
||||
```
|
||||
|
||||
示例 2:
|
||||
|
||||
|
||||
```
|
||||
输入: nums = [5,7,7,8,8,10], target = 6
|
||||
输出: 0
|
||||
```
|
||||
|
||||
|
||||
限制:
|
||||
|
||||
```
|
||||
0 <= 数组长度 <= 50000
|
||||
```
|
||||
## 题目解析
|
||||
|
||||
题目很好理解,就是要找到给定的target在排序数组中出现的次数,刚接触到算法的萌新,不仔细审题的话,会忽略排序这个重要的点。然后直接暴力循环数组,定义一个计数变量count,每次出现目标值,count加一,遍历结束,return count。
|
||||
|
||||
老司机一看到这个题,“排序”,因为数组是排序的,所以所以目标都会连在一起,我们只要找到目标值左右边界,然后相减加一就可以得到出现的次数。
|
||||
|
||||
要找到左右边界,其实可以理解为在数组中找到某个值,那么就会想到最常见的一个算法,二分法。
|
||||
|
||||
1. 定义两个指针:start,end分别指向数组的头和尾部
|
||||
2. 定义mid等于Math.ceil((start+end)/2)
|
||||
3. 判断mid指向的数组的元素和目标值target的大小
|
||||
4. mid大,那么移动end,否则移动start
|
||||
5. 重复以上的操作两遍,分别得到左边界left,右边界right
|
||||
6. 最后得到目标值出现次数 right - left + 1
|
||||
|
||||
|
||||
## 动画理解
|
||||
|
||||
|
||||
<video id="video" controls="" preload="none" >
|
||||
<source id="mp4" src="../Animation/Interview053-I- Find-Number-In-Sort-Array-I.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
## 参考代码
|
||||
|
||||
|
||||
```javaScript
|
||||
/**
|
||||
* @param {number[]} nums
|
||||
* @param {number} target
|
||||
* @return {number}
|
||||
*/
|
||||
var search = function(nums, target) {
|
||||
let start = 0;
|
||||
let mid = 0;
|
||||
let end = nums.length - 1;
|
||||
let left = 0;
|
||||
let right = 0;
|
||||
// 查找右边界
|
||||
while(start <= end) {
|
||||
mid = Math.ceil((start + end) / 2)
|
||||
if (nums[mid] <= target) {
|
||||
start = mid + 1
|
||||
} else {
|
||||
end = mid -1
|
||||
}
|
||||
}
|
||||
right = start - 1; // 右边界
|
||||
// 查找左边界
|
||||
start = 0;
|
||||
mid = 0;
|
||||
end = nums.length - 1;
|
||||
while(start <= end) {
|
||||
mid = Math.ceil((start + end) / 2)
|
||||
if (nums[mid] < target) {
|
||||
start = mid + 1
|
||||
} else {
|
||||
end = mid -1
|
||||
}
|
||||
}
|
||||
left = end + 1
|
||||
return right - left + 1
|
||||
};
|
||||
```
|
||||
|
||||
## 复杂度分析
|
||||
|
||||
二分查找的时间复杂度计算如下:假设一个数组长度为n,每次查找后数据长度减半,第一次查找后数据长度为n/2,第二次查找后数据长度为n/(2的2次方),第k次查找后数据长度为n/(2的k次方),最坏情况下数数据长度为1时找到该数,即n/(2的k次方)=1, 解得k=log2(N).
|
||||
|
||||
时间复杂度为:O(log2n)。
|
||||
|
||||
![](../../Pictures/qrcode.jpg)
|
Loading…
Reference in New Issue
Block a user