auto commit

This commit is contained in:
CyC2018
2020-11-17 00:32:18 +08:00
parent f5ad47b470
commit 7e61fc1360
380 changed files with 2371 additions and 46715 deletions

View File

@ -1,10 +1,12 @@
# Leetcode 题解 - 二分查找
<!-- GFM-TOC -->
* [1. 求开方](#1-求开方)
* [2. 大于给定元素的最小元素](#2-大于给定元素的最小元素)
* [3. 有序数组的 Single Element](#3-有序数组的-single-element)
* [4. 第一个错误的版本](#4-第一个错误的版本)
* [5. 旋转数组的最小数字](#5-旋转数组的最小数字)
* [6. 查找区间](#6-查找区间)
* [Leetcode 题解 - 二分查找](#leetcode-题解---二分查找)
* [1. 求开方](#1-求开方)
* [2. 大于给定元素的最小元素](#2-大于给定元素的最小元素)
* [3. 有序数组的 Single Element](#3-有序数组的-single-element)
* [4. 第一个错误的版本](#4-第一个错误的版本)
* [5. 旋转数组的最小数字](#5-旋转数组的最小数字)
* [6. 查找区间](#6-查找区间)
<!-- GFM-TOC -->
@ -75,12 +77,12 @@ public int binarySearch(int[] nums, int key) {
该实现和正常实现有以下不同
- h 的赋值表达式为 h = m
- 循环条件为 l < h
- 循环条件为 l \< h
- 最后返回 l 而不是 -1
nums[m] >= key 的情况下可以推导出最左 key 位于 [l, m] 区间中这是一个闭区间h 的赋值表达式为 h = m因为 m 位置也可能是解
nums[m] \>= key 的情况下可以推导出最左 key 位于 [l, m] 区间中这是一个闭区间h 的赋值表达式为 h = m因为 m 位置也可能是解
h 的赋值表达式为 h = m 的情况下如果循环条件为 l <= h那么会出现循环无法退出的情况因此循环条件只能是 l < h以下演示了循环条件为 l <= h 时循环无法退出的情况
h 的赋值表达式为 h = m 的情况下如果循环条件为 l \<= h那么会出现循环无法退出的情况因此循环条件只能是 l \< h以下演示了循环条件为 l \<= h 时循环无法退出的情况
```text
nums = {0, 1, 2}, key = 1
@ -94,7 +96,7 @@ l m h
当循环体退出时不表示没有查找到 key因此最后返回的结果不应该为 -1为了验证有没有查找到需要在调用端判断一下返回位置上的值和 key 是否相等
# 1. 求开方
## 1. 求开方
69\. Sqrt(x) (Easy)
@ -111,7 +113,7 @@ Explanation: The square root of 8 is 2.82842..., and since we want to return an
一个数 x 的开方 sqrt 一定在 0 \~ x 之间并且满足 sqrt == x / sqrt可以利用二分查找在 0 \~ x 之间查找 sqrt
对于 x = 8它的开方是 2.82842...最后应该返回 2 而不是 3在循环条件为 l <= h 并且循环退出时h 总是比 l 1也就是说 h = 2l = 3因此最后的返回值应该为 h 而不是 l
对于 x = 8它的开方是 2.82842...最后应该返回 2 而不是 3在循环条件为 l \<= h 并且循环退出时h 总是比 l 1也就是说 h = 2l = 3因此最后的返回值应该为 h 而不是 l
```java
public int mySqrt(int x) {
@ -134,7 +136,7 @@ public int mySqrt(int x) {
}
```
# 2. 大于给定元素的最小元素
## 2. 大于给定元素的最小元素
744\. Find Smallest Letter Greater Than Target (Easy)
@ -170,7 +172,7 @@ public char nextGreatestLetter(char[] letters, char target) {
}
```
# 3. 有序数组的 Single Element
## 3. 有序数组的 Single Element
540\. Single Element in a Sorted Array (Medium)
@ -185,11 +187,11 @@ Output: 2
要求以 O(logN) 时间复杂度进行求解因此不能遍历数组并进行异或操作来求解这么做的时间复杂度为 O(N)
index Single Element 在数组中的位置 index 之后数组中原来存在的成对状态被改变如果 m 为偶数并且 m + 1 < index那么 nums[m] == nums[m + 1]m + 1 >= index那么 nums[m] != nums[m + 1]
index Single Element 在数组中的位置 index 之后数组中原来存在的成对状态被改变如果 m 为偶数并且 m + 1 \< index那么 nums[m] == nums[m + 1]m + 1 \>= index那么 nums[m] != nums[m + 1]
从上面的规律可以知道如果 nums[m] == nums[m + 1]那么 index 所在的数组位置为 [m + 2, h]此时令 l = m + 2如果 nums[m] != nums[m + 1]那么 index 所在的数组位置为 [l, m]此时令 h = m
因为 h 的赋值表达式为 h = m那么循环条件也就只能使用 l < h 这种形式
因为 h 的赋值表达式为 h = m那么循环条件也就只能使用 l \< h 这种形式
```java
public int singleNonDuplicate(int[] nums) {
@ -209,7 +211,7 @@ public int singleNonDuplicate(int[] nums) {
}
```
# 4. 第一个错误的版本
## 4. 第一个错误的版本
278\. First Bad Version (Easy)
@ -219,7 +221,7 @@ public int singleNonDuplicate(int[] nums) {
如果第 m 个版本出错则表示第一个错误的版本在 [l, m] 之间 h = m否则第一个错误的版本在 [m + 1, h] 之间 l = m + 1
因为 h 的赋值表达式为 h = m因此循环条件为 l < h
因为 h 的赋值表达式为 h = m因此循环条件为 l \< h
```java
public int firstBadVersion(int n) {
@ -236,7 +238,7 @@ public int firstBadVersion(int n) {
}
```
# 5. 旋转数组的最小数字
## 5. 旋转数组的最小数字
153\. Find Minimum in Rotated Sorted Array (Medium)
@ -262,7 +264,7 @@ public int findMin(int[] nums) {
}
```
# 6. 查找区间
## 6. 查找区间
34\. Find First and Last Position of Element in Sorted Array
@ -312,10 +314,3 @@ nums = [2,2], target = 2
```
如果 h 的取值为 nums.length - 1那么 last = findFirst(nums, target + 1) - 1 = 1 - 1 = 0这是因为 findLeft 只会返回 [0, nums.length - 1] 范围的值对于 findFirst([2,2], 3) 我们希望返回 3 插入 nums 中的位置也就是数组最后一个位置再往后一个位置 nums.length所以我们需要将 h 取值为 nums.length从而使得 findFirst返回的区间更大能够覆盖 target 大于 nums 最后一个元素的情况
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>