## 二分

往常我们使用「二分」进行查值，需要确保序列本身满足「二段性」：当选定一个端点（基准值）后，结合「一段满足 & 另一段不满足」的特性来实现“折半”的查找效果。

但本题求的是峰顶索引值，如果我们选定数组头部或者尾部元素，其实无法根据大小关系“直接”将数组分成两段。

但可以利用题目发现如下性质：**由于 `arr` 数值各不相同，因此峰顶元素左侧必然满足严格单调递增，峰顶元素右侧必然不满足。**

因此 **以峰顶元素为分割点的 `arr` 数组，根据与 前一元素/后一元素 的大小关系，具有二段性：**

* 峰顶元素左侧满足 $arr[i-1] < arr[i]$ 性质，右侧不满足
* 峰顶元素右侧满足 $arr[i] > arr[i+1]$ 性质，左侧不满足

因此我们可以选择任意条件，写出若干「二分」版本。

代码：

* []

```Java
class Solution {
    // 根据 arr[i-1] < arr[i] 在 [1,n-1] 范围内找值
    // 峰顶元素为符合条件的最靠近中心的元素
    public int peakIndexInMountainArray(int[] arr) {
        int n = arr.length;
        int l = 1, r = n - 1;
        while (l < r) {
            int mid = l + r + 1 >> 1;
            if (arr[mid - 1] < arr[mid]) l = mid;
            else r = mid - 1;
        }
        return r;
    }
}
```

* []

```Java
class Solution {
    // 根据 arr[i] > arr[i+1] 在 [0,n-2] 范围内找值
    // 峰顶元素为符合条件的最靠近中心的元素值
    public int peakIndexInMountainArray(int[] arr) {
        int n = arr.length;
        int l = 0, r = n - 2;
        while (l < r) {
            int mid = l + r >> 1;
            if (arr[mid] > arr[mid + 1]) r = mid;
            else l = mid + 1;
        }
        return r;
    }
}
```

* []

```Java
class Solution {
    // 根据 arr[i-1] > arr[i] 在 [1,n-1] 范围内找值
    // 峰顶元素为符合条件的最靠近中心的元素的前一个值
    public int peakIndexInMountainArray(int[] arr) {
        int n = arr.length;
        int l = 1, r = n - 1;
        while (l < r) {
            int mid = l + r >> 1;
            if (arr[mid - 1] > arr[mid]) r = mid;
            else l = mid + 1;
        }
        return r - 1;
    }
}
```

* []

```Java
class Solution {
    // 根据 arr[i] < arr[i+1] 在 [0,n-2] 范围内找值
    // 峰顶元素为符合条件的最靠近中心的元素的下一个值
    public int peakIndexInMountainArray(int[] arr) {
        int n = arr.length;
        int l = 0, r = n - 2;
        while (l < r) {
            int mid = l + r + 1 >> 1;
            if (arr[mid] < arr[mid + 1]) l = mid;
            else r = mid - 1;
        }
        return r + 1;
    }
}
```

* 时间复杂度：$O(\log{n})$
* 空间复杂度：$O(1)$

---

## 三分

事实上，我们还可以利用「三分」来解决这个问题。

顾名思义，**「三分」就是使用两个端点将区间分成三份，然后通过每次否决三分之一的区间来逼近目标值。**

具体的，由于峰顶元素为全局最大值，因此我们可以每次将当前区间分为 $[l, m1]$、$[m1, m2]$ 和 $[m2, r]$ 三段，如果满足 $arr[m1] > arr[m2]$，说明峰顶元素不可能存在与 $[m2, r]$ 中，让 $r = m2 - 1$ 即可。另外一个区间分析同理。

代码：

* []

```Java
class Solution {
    public int peakIndexInMountainArray(int[] arr) {
        int n = arr.length;
        int l = 0, r = n - 1;
        while (l < r) {
            int m1 = l + (r - l) / 3;
            int m2 = r - (r - l) / 3;
            if (arr[m1] > arr[m2]) r = m2 - 1;
            else l = m1 + 1;
        }
        return r;
    }
}
```

* 时间复杂度：$O(\log{n})$
* 空间复杂度：$O(1)$

---

## 二分 & 三分 & k 分 ？

必须说明一点，「二分」和「三分」在渐进复杂度上都是一样的，都可以通过换底公式转化为可忽略的常数，因此两者的复杂度都是 $O(\log{n})$。

因此选择「二分」还是「三分」取决于要解决的是什么问题：

* 二分通常用来解决单调函数的找 $target$ 问题，但进一步深入我们发现只需要满足「二段性」就能使用「二分」来找分割点；
* 三分则是解决单峰函数极值问题。

**因此一般我们将「通过比较两个端点，每次否决 1/3 区间 来解决单峰最值问题」的做法称为「三分」；而不是简单根据单次循环内将区间分为多少份来判定是否为「三分」。**

随手写了一段反例代码：

* []

```Java
class Solution {
    public int peakIndexInMountainArray(int[] arr) {
        int left = 0, right = arr.length - 1;
        while(left < right) {
            int m1 = left + (right - left) / 3;
            int m2 = right - (right - left + 2) / 3;
            if (arr[m1] > arr[m1 + 1]) {
                right = m1;
            } else if (arr[m2] < arr[m2 + 1]) {
                left = m2 + 1;
            } else {
                left = m1;
                right = m2;
            }
        }
        return left;
    }
}
```

这并不是「三分」做法，最多称为「变形二分」。本质还是利用「二段性」来做分割的，只不过同时 check 了两个端点而已。

如果这算「三分」的话，那么我能在一次循环里面划分 $k - 1$ 个端点来实现 $k$ 分？

**显然这是没有意义的，因为按照这种思路写出来的所谓的「四分」、「五分」、「k 分」是需要增加同等数量的分支判断的。这时候单次 `while` 决策就不能算作 $O(1)$ 了，而是需要在 $O(k)$ 的复杂度内决定在哪个分支，就跟上述代码有三个分支进行判断一样。** 因此，这种写法只能算作是「变形二分」。

**综上，只有「二分」和「三分」的概念，不存在所谓的 $k$ 分。** 同时题解中的「三分」部分提供的做法就是标准的「三分」做法。

---

## 进阶

更进一步的，如果存在多个峰值，返回任意一个的话，是否还可以二分？为什么？

[（原题）162. 寻找峰值](https://leetcode-cn.com/problems/find-peak-element/) : [（题解）关于能够「二分」的两点证明](https://leetcode-cn.com/problems/find-peak-element/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-qva7v/)

---

## 其他「二分」内容

题目简单？考虑加餐一道 [01 背包变形题](https://mp.weixin.qq.com/s?__biz=MzU4NDE3MTEyMA==&mid=2247488868&idx=1&sn=5e54a1d091a8249d3033a28fc299076d&chksm=fd9cbe7bcaeb376d1ee8a753ebc57358e5605fc1a3b51865eb0f758fb3e6e4688e1b0acfa902&token=730964724&lang=zh_CN#rd)。

或是考虑加练如下「二分」题目 🍭🍭

| 题目                                                                                          | 题解                                                                                                                                                   | 难度 | 推荐指数 |
| --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ---- | -------- |
| [4. 寻找两个正序数组的中位数](https://leetcode-cn.com/problems/median-of-two-sorted-arrays/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/shua-chuan-lc-po-su-jie-fa-fen-zhi-jie-f-wtu2/) | 困难 | 🤩🤩🤩🤩 |
| [29. 两数相除](https://leetcode-cn.com/problems/divide-two-integers/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/divide-two-integers/solution/shua-chuan-lc-er-fen-bei-zeng-cheng-fa-j-m73b) | 中等 | 🤩🤩🤩 |
| [33. 搜索旋转排序数组](https://leetcode-cn.com/problems/search-in-rotated-sorted-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/search-in-rotated-sorted-array/solution/shua-chuan-lc-yan-ge-ologn100yi-qi-kan-q-xifo/) | 中等 | 🤩🤩🤩🤩🤩 |
| [34. 在排序数组中查找元素的第一个和最后一个位置](https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/sha-sha-gao-bu-qing-ru-he-ding-yi-er-fen-rrj1/) | 中等 | 🤩🤩🤩🤩🤩 |
| [35. 搜索插入位置](https://leetcode-cn.com/problems/search-insert-position/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/search-insert-position/solution/shua-chuan-lc-jian-dan-mo-ni-ti-by-ac_oi-7d5t/) | 简单 | 🤩🤩🤩🤩🤩 |
| [74. 搜索二维矩阵](https://leetcode-cn.com/problems/search-a-2d-matrix/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/search-a-2d-matrix/solution/gong-shui-san-xie-yi-ti-shuang-jie-er-fe-l0pq/) | 中等 | 🤩🤩🤩🤩 |
| [81. 搜索旋转排序数组 II](https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/solution/gong-shui-san-xie-xiang-jie-wei-he-yuan-xtam4//) | 中等 | 🤩🤩🤩🤩 |
| [153. 寻找旋转排序数组中的最小值](https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/solution/gong-shui-san-xie-yan-ge-olognyi-qi-kan-6d969/) | 中等 | 🤩🤩🤩 |
| [154. 寻找旋转排序数组中的最小值 II](https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/solution/gong-shui-san-xie-xiang-jie-wei-he-yuan-7xbty/) | 困难 | 🤩🤩🤩 |
| [162. 寻找峰值](https://leetcode-cn.com/problems/find-peak-element/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-peak-element/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-qva7v/) | 中等 | 🤩🤩🤩🤩🤩 |
| [220. 存在重复元素 III](https://leetcode-cn.com/problems/contains-duplicate-iii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/contains-duplicate-iii/solution/gong-shui-san-xie-yi-ti-shuang-jie-hua-d-dlnv/) | 中等 | 🤩🤩🤩 |
| [274. H 指数](https://leetcode-cn.com/problems/h-index/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/h-index/solution/gong-shui-san-xie-li-yong-er-duan-xing-z-1jxw/) | 中等 | 🤩🤩🤩 |
| [275. H 指数 II](https://leetcode-cn.com/problems/h-index-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/h-index-ii/solution/gong-shui-san-xie-liang-chong-er-fen-ji-sovjb/) | 中等 | 🤩🤩🤩 |
| [278. 第一个错误的版本](https://leetcode-cn.com/problems/first-bad-version/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/first-bad-version/solution/gong-shui-san-xie-shi-yong-jiao-hu-han-s-8hpv/) | 简单 | 🤩🤩🤩🤩 |
| [352. 将数据流变为多个不相交区间](https://leetcode-cn.com/problems/data-stream-as-disjoint-intervals/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/data-stream-as-disjoint-intervals/solution/gong-shui-san-xie-yi-ti-shuang-jie-er-fe-afrk/) | 困难 | 🤩🤩🤩🤩 |
| [354. 俄罗斯套娃信封问题](https://leetcode-cn.com/problems/russian-doll-envelopes/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/russian-doll-envelopes/solution/zui-chang-shang-sheng-zi-xu-lie-bian-xin-6s8d/) | 困难 | 🤩🤩🤩 |
| [363. 矩形区域不超过 K 的最大数值和](https://leetcode-cn.com/problems/max-sum-of-rectangle-no-larger-than-k/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/max-sum-of-rectangle-no-larger-than-k/solution/gong-shui-san-xie-you-hua-mei-ju-de-ji-b-dh8s/) | 困难 | 🤩🤩🤩 |
| [374. 猜数字大小](https://leetcode-cn.com/problems/guess-number-higher-or-lower/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/guess-number-higher-or-lower/solution/gong-shui-san-xie-shi-yong-jiao-hu-han-s-tocm/) | 简单 | 🤩🤩🤩 |
| [441. 排列硬币](https://leetcode-cn.com/problems/arranging-coins/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/arranging-coins/solution/gong-shui-san-xie-yi-ti-shuang-jie-shu-x-sv9o/) | 简单 | 🤩🤩🤩 |
| [528. 按权重随机选择](https://leetcode-cn.com/problems/random-pick-with-weight/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/random-pick-with-weight/solution/gong-shui-san-xie-yi-ti-shuang-jie-qian-8bx50/) | 中等 | 🤩🤩🤩🤩 |
| [611. 有效三角形的个数](https://leetcode-cn.com/problems/valid-triangle-number/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/valid-triangle-number/solution/gong-shui-san-xie-yi-ti-san-jie-jian-dan-y1we/) | 中等 | 🤩🤩🤩🤩 |
| [704. 二分查找](https://leetcode-cn.com/problems/binary-search/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/binary-search/solution/gong-shui-san-xie-yun-yong-er-fen-zhao-f-5jyj/) | 简单 | 🤩🤩🤩🤩🤩 |
| [778. 水位上升的泳池中游泳](https://leetcode-cn.com/problems/swim-in-rising-water/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/swim-in-rising-water/solution/gong-shui-san-xie-yi-ti-shuang-jie-krusk-7c6o/) | 困难 | 🤩🤩🤩 |
| [852. 山脉数组的峰顶索引](https://leetcode-cn.com/problems/peak-index-in-a-mountain-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/peak-index-in-a-mountain-array/solution/gong-shui-san-xie-er-fen-san-fen-cha-zhi-5gfv/) | 简单 | 🤩🤩🤩🤩🤩 |
| [981. 基于时间的键值存储](https://leetcode-cn.com/problems/time-based-key-value-store/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/time-based-key-value-store/solution/gong-shui-san-xie-yi-ti-shuang-jie-ha-xi-h5et/) | 中等 | 🤩🤩🤩🤩 |
| [1004. 最大连续1的个数 III](https://leetcode-cn.com/problems/max-consecutive-ones-iii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/max-consecutive-ones-iii/solution/san-chong-jie-fa-cong-dong-tai-gui-hua-d-gxks/) | 中等 | 🤩🤩🤩 |
| [1011. 在 D 天内送达包裹的能力](https://leetcode-cn.com/problems/capacity-to-ship-packages-within-d-days/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/capacity-to-ship-packages-within-d-days/solution/gong-shui-san-xie-li-yong-er-duan-xing-z-95zj/) | 中等 | 🤩🤩🤩🤩 |
| [1208. 尽可能使字符串相等](https://leetcode-cn.com/problems/get-equal-substrings-within-budget/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/get-equal-substrings-within-budget/solution/ni-bu-ke-neng-kan-bu-dong-de-qian-zhui-h-u4l1/) | 中等 | 🤩🤩🤩 |
| [1337. 矩阵中战斗力最弱的 K 行](https://leetcode-cn.com/problems/the-k-weakest-rows-in-a-matrix/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/the-k-weakest-rows-in-a-matrix/solution/gong-shui-san-xie-yi-ti-shuang-jie-po-su-7okx/) | 简单 | 🤩🤩🤩 |
| [1438. 绝对差不超过限制的最长连续子数组](https://leetcode-cn.com/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit/solution/xiang-jie-er-fen-hua-dong-chuang-kou-dan-41g1/) | 中等 | 🤩🤩🤩      |
| [1482. 制作 m 束花所需的最少天数](https://leetcode-cn.com/problems/minimum-number-of-days-to-make-m-bouquets/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/minimum-number-of-days-to-make-m-bouquets/solution/gong-shui-san-xie-li-yong-er-duan-xing-z-ysv4/) | 中等 | 🤩🤩🤩 |
| [1707. 与数组中元素的最大异或值](https://leetcode-cn.com/problems/maximum-xor-with-an-element-from-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximum-xor-with-an-element-from-array/solution/gong-shui-san-xie-jie-zhe-ge-wen-ti-lai-lypqr/) | 困难 | 🤩🤩🤩 |
| [1713. 得到子序列的最少操作次数](https://leetcode-cn.com/problems/minimum-operations-to-make-a-subsequence/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/minimum-operations-to-make-a-subsequence/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-oj7yu/) | 困难 | 🤩🤩🤩 |
| [1751. 最多可以参加的会议数目 II](https://leetcode-cn.com/problems/maximum-number-of-events-that-can-be-attended-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximum-number-of-events-that-can-be-attended-ii/solution/po-su-dp-er-fen-dp-jie-fa-by-ac_oier-88du/) | 困难 | 🤩🤩🤩      |
| [1818. 绝对差值和](https://leetcode-cn.com/problems/minimum-absolute-sum-difference/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/minimum-absolute-sum-difference/solution/gong-shui-san-xie-tong-guo-er-fen-zhao-z-vrmq/) | 中等 | 🤩🤩🤩🤩🤩 |
| [1838. 最高频元素的频数](https://leetcode-cn.com/problems/frequency-of-the-most-frequent-element/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/frequency-of-the-most-frequent-element/solution/gong-shui-san-xie-cong-mei-ju-dao-pai-xu-kxnk/) | 中等 | 🤩🤩🤩 |
| [1894. 找到需要补充粉笔的学生编号](https://leetcode-cn.com/problems/find-the-student-that-will-replace-the-chalk/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-the-student-that-will-replace-the-chalk/solution/gong-shui-san-xie-yi-ti-shuang-jie-qian-kpqsk/) | 中等 | 🤩🤩🤩🤩 |
| [剑指 Offer 53 - I. 在排序数组中查找数字 I](https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/solution/gong-shui-san-xie-liang-chong-er-fen-ton-3epx/) | 简单 | 🤩🤩🤩🤩🤩 |

**注：以上目录整理来自 [wiki](https://github.com/SharingSource/LogicStack-LeetCode/wiki/二分)，任何形式的转载引用请保留出处。**
