【LeetCode】二分 binary_search(共58题)
【4】Median of Two Sorted Arrays
【29】Divide Two Integers
【33】Search in Rotated Sorted Array
【34】Find First and Last Position of Element in Sorted Array
【35】Search Insert Position
【50】Pow(x, n)
【69】Sqrt(x)
【74】Search a 2D Matrix (2019年1月25日,谷歌tag复习)剑指offer原题
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
- Integers in each row are sorted from left to right.
- The first integer of each row is greater than the last integer of the previous row.
Example 1:
Input:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 3
Output: true
Example 2:
Input:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 13
Output: false
题解:用 target 和当前右上角元素做比较,如果相等返回 true,如果不想等,如果右上角元素大于target,那么删除这一列,如果右上角元素小于target,那么删除这一行。
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if (matrix.empty() || matrix[].empty()) {
return false;
}
const int n = matrix.size(), m = matrix[].size();
int up = , right = m-;
while (up < n && right >= ) {
if (matrix[up][right] == target) {
return true;
}
if (matrix[up][right] < target) {
up++;
} else if (matrix[up][right] > target) {
--right;
}
}
return false;
}
};
【81】Search in Rotated Sorted Array II
【153】Find Minimum in Rotated Sorted Array
【154】Find Minimum in Rotated Sorted Array II
【162】Find Peak Element (2018年11月27日)(本题需要复习,一开始不会做的。我觉得二分也容易写错的。)
这题要求我们在一个无序的数组里找到一个peak元素,所谓peak,就是值比两边邻居大就可以了。
题解:对于这道题目,最简单的解法就是遍历数组,只要找到第一个符合要求的元素就可以了,时间复杂度为O(n),但是这题要求O(LogN)的时间复杂度,还可以用二分来做。https://blog.csdn.net/NK_test/article/details/49926229
首先我们找到中间节点mid,如果大于两边返回当前的index就可以了,如果左边的节点比mid大,那么我们可以继续在左半区间查找,这里面一定存在一个peak,为什么这么说呢?假设此时的区间范围为[0,mid-1],因为num[mid-1]一定大于num[mid],如果num[mid-2]<=num[mid-1],那么num[mid-1]就是一个peak。如果num[mid-2]>num[mid-1],那么我们就继续在[0,mid-2]区间查找,因为num[-1]为负无穷,所以我们最终绝对能在左半区间找到一个peak。同理右半区间一样。
class Solution {
public:
int findPeakElement(vector<int>& nums) {
const int n = nums.size();
int left = , right = n - ;
while (left < right) {
int mid = (left + right) / ;
int target = nums[mid+];
if (nums[mid] < target) {
left = mid + ;
} else {
right = mid;
}
}
return left;
}
};
2019年4月15日更新。我们可以根据mid和旁边元素的大小来移动指针。我们的目标其实是把搜索方向放到元素增大的一侧。
如果我们把二分写成如下的形式,那么可以发现,当 left = right 的时候退出循环,mid 永远取不到 right,那么 mid + 1 也就永远合法。
class Solution {
public:
int findPeakElement(vector<int>& nums) {
const int n = nums.size();
int left = , right = n-;
while (left < right) {
int mid = (left + right) / ;
if (nums[mid] < nums[mid+]) {
left = mid + ;
} else {
right = mid;
}
}
return left;
}
};
【167】Two Sum II - Input array is sorted
【174】Dungeon Game
【209】Minimum Size Subarray Sum
【222】Count Complete Tree Nodes
【230】Kth Smallest Element in a BST
【240】Search a 2D Matrix II (2019年1月26日,谷歌tag复习)
write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
- Integers in each row are sorted in ascending from left to right.
- Integers in each column are sorted in ascending from top to bottom.
题解:很多种方法可以做,我还是每次看右上角元素。
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if (matrix.empty() || matrix[].empty()) {
return false;
}
const int n = matrix.size(), m = matrix[].size();
int up = , right = m-;
while (up < n && right >= ) {
if (matrix[up][right] == target) {
return true;
}
while (up < n && matrix[up][right] < target) {
++up;
}
if (up == n) { break; }
while (right >= && matrix[up][right] > target) {
--right;
}
}
return false;
}
};
【270】Closest Binary Search Tree Value ()
【275】H-Index II
【278】First Bad Version (2018年12月22日,地里面经)
给了一个数字 n, 代表数组 [1..n],给了一个 api, bool isBadVersion(int version); 能判断一个数字是不是 bad version。在调用这个给定的api最小次数的前提下,返回这个数组中第一个bad version。
题解:二分,lower_bound 自己实现
// Forward declaration of isBadVersion API.
bool isBadVersion(int version); class Solution {
public:
int firstBadVersion(int n) {
long long left = , right = (long long)n + ;
long long mid;
while (left < right) {
mid = left + (right - left) / ;
if (!isBadVersion(mid)) {
left = mid + ;
} else {
right = mid;
}
}
return left;
}
};
【287】Find the Duplicate Number (2019年1月26日,二分查找)
给了一个nums数组,里面包含 1 — n-1 的数字,有一个数字可能重复了2次到多次。找出来这个数。
题解:解法1. sort + 2 pointers
class Solution {
public:
int findDuplicate(vector<int>& nums) {
sort(nums.begin(), nums.end());
for (int i = ; i < nums.size() - ; ++i) {
if (nums[i] == nums[i+]) {
return nums[i];
}
}
return -;
}
};
解法2. 二分==总写错啊
【300】Longest Increasing Subsequence
【302】Smallest Rectangle Enclosing Black Pixels (2019年1月26日,谷歌tag题)
给了一个矩阵,0代表白色像素,1代表黑色像素,黑色所有的像素是四联通的,问把黑色所有像素的包围起来的最小矩形面积。
题解:这题是个二分 tag,但是我只会用dfs解法。dfs解法时间复杂度是O(mn)的。我们需要找四个值,1像素的最左,最右,最上和最下。然后用矩阵的长和宽相乘一下就可以了。
class Solution {
public:
int minArea(vector<vector<char>>& image, int x, int y) {
if (image.size() == || image[].size() == ) {
return ;
}
n = image.size(), m = image[].size();
vector<vector<int>> visit(n, vector<int>(m, ));
left = right = y;
top = buttom = x;
dfs(image, x, y, visit);
int area = (right - left + ) * (buttom - top + );
return area;
}
int n, m;
int left = -, right = -, top = -, buttom = -;
void dfs(const vector<vector<char>>& image, int x, int y, vector<vector<int>>& visit) {
visit[x][y] = ;
left = min(left, y), right = max(right, y);
top = min(top, x), buttom = max(buttom, x);
for (int k = ; k < ; ++k) {
int newx = x + dirx[k], newy = y + diry[k];
if (newx >= && newx < n && newy >= && newy < m && image[newx][newy] == '' && !visit[newx][newy]) {
dfs(image, newx, newy, visit);
}
}
return;
}
int dirx[] = {-, , , };
int diry[] = {, -, , };
};
【349】Intersection of Two Arrays (2018年11月6日,算法群相关题)
hash-table 里面有这题,hash-table:https://www.cnblogs.com/zhangwanying/p/9886262.html
也可以二分解答,二分没有想过,我估计就是先排序,然后二分吧
【350】Intersection of Two Arrays II (2018年11月6日,算法群)
hash-table 里面有这题,hash-table:https://www.cnblogs.com/zhangwanying/p/9886262.html
也可以二分解答,二分没有想过,我估计就是先排序,然后二分吧
【354】Russian Doll Envelopes
【363】Max Sum of Rectangle No Larger Than K
【367】Valid Perfect Square
【374】Guess Number Higher or Lower (2019年1月25日,谷歌tag复习)
在 [1, n] 这个区间里面猜数,给了一个 guess 的api,返回一开始 pick 的数字。
You call a pre-defined API guess(int num)
which returns 3 possible results (-1
, 1
, or 0
):
-1 : My number is lower
1 : My number is higher
0 : Congrats! You got it!
题解:二分,这题我写成了左闭右闭的形式。
// Forward declaration of guess API.
// @param num, your guess
// @return -1 if my number is lower, 1 if my number is higher, otherwise return 0
int guess(int num); class Solution {
public:
int guessNumber(int n) {
int left = , right = n;
long long mid;
while (left <= right) {
mid = (long long)left + (right - left) / ;
int res = guess(mid);
if (res == ) {
return mid;
} else if (res < ) { //leftside
right = mid - ;
} else {
left = mid + ;
}
}
return -;
}
};
【378】Kth Smallest Element in a Sorted Matrix (2019年2月9日)
给了一个 n * n 的矩阵,返回矩阵中第 k 小的元素。
题解:二分答案。我们要找到一个最小的元素x,满足矩阵中的元素小于等于x的值的有k个。(lower_bound)
class Solution {
public:
int kthSmallest(vector<vector<int>>& matrix, int k) {
const int n = matrix.size();
int left = matrix[][], right = matrix[n-][n-] + ;
while (left < right) {
int mid = left + ((right - left) / );
int tot = ;
for (auto& row : matrix) {
auto iter = upper_bound(row.begin(), row.end(), mid);
tot += distance(row.begin(), iter);
}
// printf("left = %d, right = %d, mid = %d, tot = %d\n", left, right, mid, tot);
if (tot < k) {
left = mid + ;
} else {
right = mid;
}
}
return left;
}
};
【392】Is Subsequence
【410】Split Array Largest Sum (2019年3月2日,谷歌tag)
给了一个连续的数组,每个元素代表任务完成的时间,然后给了一个天数m,要求这些任务必须在m天之内完成(可以提前)但是这些任务必须按顺序做,求最小化这这些天花在任务上时间的最大值。
举个例子:
nums = [7,2,5,10,8]
m = 2
Output:
18 Explanation:
There are four ways to split nums into two subarrays.
The best way is to split it into [7,2,5] and [10,8],
where the largest sum among the two subarrays is only 18.
题解:我们其实可以枚举这个时间,我们假设一天最多做 k 个小时,看 m 天之内能不能完成。如果不能的话,我们尝试扩大k,如果可以的话,我们尝试缩小k。所以二分查找的思路就出来了。left 边界是数组的最大值,right边界是整个数组的和。
整体时间复杂度是 O(nlogn)
class Solution {
public:
int splitArray(vector<int>& nums, int m) {
const int n = nums.size();
long long left = -, right = ;
for (auto& num : nums) {
right += num;
if (num > left) {
left = num;
}
}
int res(-);
while (left <= right) {
long long mid = left + (right - left) / ;
if (check(nums, mid, m)) {
res = mid;
right = mid - ;
} else {
left = mid + ;
}
}
return res;
}
bool check(vector<int>& nums, long long mid, int m) {
int cnt = ; long long sum = 0LL;
for (auto num : nums) {
if (sum + num <= mid) {
sum += num;
} else {
cnt++;
sum = num;
if (cnt == m || sum > mid) {return false;}
}
}
return true;
}
};
【436】Find Right Interval
【441】Arranging Coins (2018年11月26日)
给了 n 枚硬币, 我们排列这些硬币,第一行放1个,第二行放2个,.. ,第 k 行放 k 个。问这 n 个硬币最多能完全放满多少行。
题解:我一个解法是用 等差数列的公式求解的, k * (k + 1) <= 2 * n。 枚举 k, 找到最大满足条件的 k,然后 返回 k . 这个解法只能 beats 20%+。
后来我看是二分的tag,我就写了一个 二分,然后就beats 90+了。
class Solution {
public:
int arrangeCoins(int n) {
int k = my_upper_bound(, (long long)n + , (long long)n * );
return k - ;
}
int my_upper_bound(int begin, long long end, long long target) {
long long mid = ;
while (begin < end) {
mid = ((long long)begin + end) / ;
long long temp = mid * (mid + );
if (temp > target) {
end = mid;
} else {
begin = mid + ;
}
}
return begin;
}
};
【454】4Sum II
【475】Heaters (2019年2月26日)
给了一个房子数组和一个暖气数组,求暖气的最小半径,要求所有的房子必须被暖气覆盖。
题解:对于每一个房子求离它最近的暖气,用 lower_bound 求,然后用这个半径和 global_max 做比较。时间复杂度是 O(nlogn)
class Solution {
public:
int findRadius(vector<int>& houses, vector<int>& heaters) {
sort(heaters.begin(), heaters.end());
int res = ;
for (auto& pos : houses) {
auto iter = lower_bound(heaters.begin(), heaters.end(), pos);
int radius = ;
if (iter == heaters.begin()) {
radius = *iter - pos;
} else if (iter == heaters.end()) {
--iter;
radius = pos - *iter;
} else {
radius = min(*iter - pos, pos - *(iter-));
}
res = max(res, radius);
}
return res;
}
};
【483】Smallest Good Base
【497】Random Point in Non-overlapping Rectangles
【528】Random Pick with Weight
【644】Maximum Average Subarray II
【658】Find K Closest Elements
【668】Kth Smallest Number in Multiplication Table
【702】Search in a Sorted Array of Unknown Size (2019年1月26日,二分查找复习,谷歌tag,lower_bound思想, M)
给了一个不知道长度的array,问target是否存在在array中。ArrayReader.get(k) 能获取 index = k的值。数据范围:
You may assume all integers in the array are less than 10000
, and if you access the array out of bounds, ArrayReader.get
will return 2147483647
.
- You may assume that all elements in the array are unique.
- The value of each element in the array will be in the range
[-9999, 9999]
.
题解:我推算出数组最长为 20000,所以left = 0, right = 20000,直接用lower_bound, 如果说 reader.get(mid) 这个数字是 INT_MAX 的话,right = mid,丢弃所有右边的。如果说 reader.get(mid) < target 的话,那么说明,mid 这个依旧不满足条件,我们需要把整个左边和mid一起丢掉 left = mid + 1。剩下的话,就是 right = mid
// Forward declaration of ArrayReader class.
class ArrayReader; class Solution {
public:
int search(const ArrayReader& reader, int target) {
long long left = , right = , mid = ;
while (left < right) {
mid = (left + right) / ;
int temp = reader.get(mid);
if (temp == INT_MAX) {
right = mid;
} else if (temp < target) {
left = mid + ;
} else {
right = mid;
}
}
if (reader.get(left) == target) {
return left;
}
return -;
}
};
【704】Binary Search
【710】Random Pick with Blacklist
【718】Maximum Length of Repeated Subarray
【719】Find K-th Smallest Pair Distance
【744】Find Smallest Letter Greater Than Target
【774】Minimize Max Distance to Gas Station
【778】Swim in Rising Water
【786】K-th Smallest Prime Fraction
【793】Preimage Size of Factorial Zeroes Function
【852】Peak Index in a Mountain Array (2019年2月27日,google tag)
给了一个三角顺序的数组,(前半段递增,后半段递减),返回值最大的元素下标。
Example 1:
Input: [0,1,0]
Output: 1
Example 2:
Input: [0,2,1,0]
Output: 1
题解:二分,如果遍历一遍就行的话,这就不应该是一个面试题。时间复杂度是 O(logN)
如果 nums[mid] < nums[mid+1], 说明mid还在递增的区间,我们这个时候应该++left。
不然如果 nums[mid-1] < nums[mid] > nums[mid+1],说明mid已经是我们寻找的目标值。
再或者 nums[mid-1] > nums[mid], 说明现在已经在递减的区间。我们应该 right = mid
class Solution {
public:
int peakIndexInMountainArray(vector<int>& A) {
const int n = A.size();
int left = , right = n;
while (left < right) {
int mid = (left + right) / ;
if (mid + < right && A[mid] < A[mid+]) {
left = mid + ;
} else if (mid - >= left && A[mid-] < A[mid]) {
return mid;
} else {
right = mid;
}
}
return left;
}
};
【862】Shortest Subarray with Sum at Least K
【875】Koko Eating Bananas
【878】Nth Magical Number
【887】Super Egg Drop
【LeetCode】二分 binary_search(共58题)的更多相关文章
- Leetcode 简略题解 - 共567题
Leetcode 简略题解 - 共567题 写在开头:我作为一个老实人,一向非常反感骗赞.收智商税两种行为.前几天看到不止两三位用户说自己辛苦写了干货,结果收藏数是点赞数的三倍有余,感觉自己的 ...
- 剑指offer 面试58题
面试58题: 题目:翻转字符串 题:牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意 ...
- 【LeetCode】数学(共106题)
[2]Add Two Numbers (2018年12月23日,review) 链表的高精度加法. 题解:链表专题:https://www.cnblogs.com/zhangwanying/p/979 ...
- 【LeetCode】哈希表 hash_table(共88题)
[1]Two Sum (2018年11月9日,k-sum专题,算法群衍生题) 给了一个数组 nums, 和一个 target 数字,要求返回一个下标的 pair, 使得这两个元素相加等于 target ...
- 【LeetCode】树(共94题)
[94]Binary Tree Inorder Traversal [95]Unique Binary Search Trees II (2018年11月14日,算法群) 给了一个 n,返回结点是 1 ...
- 【LeetCode】双指针 two_pointers(共47题)
[3]Longest Substring Without Repeating Characters [11]Container With Most Water [15]3Sum (2019年2月26日 ...
- 【LeetCode】设计题 design(共38题)
链接:https://leetcode.com/tag/design/ [146]LRU Cache [155]Min Stack [170]Two Sum III - Data structure ...
- 【LeetCode】堆 heap(共31题)
链接:https://leetcode.com/tag/heap/ [23] Merge k Sorted Lists [215] Kth Largest Element in an Array (无 ...
- 【LeetCode】排序 sort(共20题)
链接:https://leetcode.com/tag/sort/ [56]Merge Intervals (2019年1月26日,谷歌tag复习) 合并区间 Input: [[1,3],[2,6], ...
随机推荐
- shell 中使用正则表达式
ls | xargs echo | sed 's/.*\(\w\+\)\s\(\w\+\s\)*\1d.*/\1/' 说明 \w\+表示一段连续的字符串 \s\+ 一个或者多个空格 \s* 0个或者多 ...
- Ubuntu 系统搭建LNMP环境
当前Linux版本:Ubuntu16.04 一.安装Nginx 在终端中输入命令 " sudo apt-get install nginx ",在确认安装完成后,在浏览器中访问 l ...
- grep匹配单词, 匹配单词开始, 匹配^ 的区别
grep '^.....$' 是指, 匹配整个这个行中, 以什么开头, 以什么结尾. 指的是整行, 不是某个单词. grep -w (word) 指的是匹配整个单词, 而不能是单词的一部分, 如: g ...
- nginx坑记录
问题1: 配置解析过程使用ngx_cycle->pool申请内存保存配置,结果造成野指针. 背景:需求开发过程,有一些结构需要在配置解析阶段保存,然后可以动态修改.看原来的代码配置解析都是使用c ...
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_08 转换流_2_编码引出的问题_FileReader读取GBK格式文件
IDEA默认的编码格式是UTF-8 新建一个txt文件.输入你好 ANSI就是系统默认编码.保存即可. 通过IDE打开是乱码的,因为默认打开的方式是UTF-8 转换为char类型 输出了乱码
- python 正则表达式 re.split
内置函数split与re库中的split,有很多相似处 #!use/bin/python #coding:utf-8 import re str= "https://i.cnb1logs.c ...
- memset, fill 对bool,int 赋值的效率
memset对bool型变量赋false比对int型变量赋0快了10倍 fill对bool型变量赋false和对int型变量赋0效率一样 fill对int型变量赋0比memset对int型变量赋0慢了 ...
- vue通信之子父组件通信
子父组件通信: 创建一个父组件 Home , 创建一个子组件 Head Home 组件: import Head from "./Head.vue" // 引入 Head 组件 c ...
- JavaSE编码试题强化练习2
1.编写递归算法程序:一列数的规则如下: 0.1.1.2.3.5.8.13.21.34...... 求数列的第40位数是多少. public class TestRecursion { public ...
- CentOS7 redhat7 linux系统1分钟安装Zabbix web 监控 服务器
一.准备工作OS:centos7.4Zabbix version:3.4.6(2018/1/15日上线的新版本)Database:MariaDB关闭防火墙:systemctl stop firewal ...