题目列表
- Leetcode 34 在排序数组中查找元素的第一个和最后一个位置:
https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/ - Leetcode 35 搜索插入位置
https://leetcode-cn.com/problems/search-insert-position/ - Leetcode 74 搜索二维矩阵
https://leetcode-cn.com/problems/search-a-2d-matrix/ - Leetcode 611 有效三角形的个数
https://leetcode-cn.com/problems/valid-triangle-number/ - Leetcode 852 山脉数组的峰顶索引
https://leetcode-cn.com/problems/peak-index-in-a-mountain-array/ - Leetcode 1011 在 D 天内送达包裹的能力
https://leetcode-cn.com/problems/capacity-to-ship-packages-within-d-days/ - Leetcode 1818 绝对差值和
https://leetcode-cn.com/problems/minimum-absolute-sum-difference/
知识点
- 二叉搜索(要求肯定是有序,支持随机存储的数据结构)
- 主要适合查找有序数组中的具体某个值
- 模板(有的时候自己写不统一,检查特殊情况比如搜索到边界或者不存在等要检查,很是麻烦):
vector<int> search(vector<int> &nums, int target) { int l = 0, r = nums.size() - 1, i = 0; while (l < r) { // 二分查找 i = (l + r) / 2; if (nums[i] < target) { l = i + 1; } else if (nums[i] >= target) { // 直接else当然也可以,这样方便记忆 r = i; } } }
- 取左边一半的时候
r = i
,右指针替换为i
。而在取右边一半的时候l = i + 1
,左指针替换为i
的后一个。 - 每次只需要判断
nums[l] == target
即可确定是否找到target
- (这条只是参考,需要灵活使用二叉搜索)在升序情况下,如果当前
target
不存在(即nums[l] != target
)且小于第一个元素,则l=0
;如果当前target
不存在且大于最后元素,则l=最后一个元素的索引
;如果当前target
不存在且介于数组中间,则会返回比target
元素大的第一个位置。 - 当然模板只是固定的,实际做题的时候可以进行修改,保证搜索的正确性,比如二分时候可以
(i = (l + r + 1) / 2)
等等
思路及代码
Leetcode 34 在排序数组中查找元素的第一个和最后一个位置
- 要查找元素的第一个位置和最后一个位置且已知是升序排列,我们首先进行二分查找(Line 8-15),找到
target
(没有找到->返回{-1,-1}
即可)。在找到target
元素后,我们向两边扩散搜素第一个和最后一个的位置(Line 17-23)即可。 - 代码:
class Solution { public: vector<int> searchRange(vector<int> &nums, int target) { if (nums.size() == 0) return vector<int>({ -1, -1}); // 特判 int l = 0, r = nums.size() - 1, i = 0; vector<int> ans({ -1, -1}); while (l < r) { // 二分查找 i = (l + r) / 2; if (nums[i] < target) { l = i + 1; } else if (nums[i] >= target) { r = i; } } if (nums[l] == target) { i = l, l = i, r = i; while (l >= 0 && nums[l] == nums[i]) l--; while (r < nums.size() && nums[r