【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 (-11, 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.

  1. You may assume that all elements in the array are unique.
  2. 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题)的更多相关文章

  1. Leetcode 简略题解 - 共567题

    Leetcode 简略题解 - 共567题     写在开头:我作为一个老实人,一向非常反感骗赞.收智商税两种行为.前几天看到不止两三位用户说自己辛苦写了干货,结果收藏数是点赞数的三倍有余,感觉自己的 ...

  2. 剑指offer 面试58题

    面试58题: 题目:翻转字符串 题:牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意 ...

  3. 【LeetCode】数学(共106题)

    [2]Add Two Numbers (2018年12月23日,review) 链表的高精度加法. 题解:链表专题:https://www.cnblogs.com/zhangwanying/p/979 ...

  4. 【LeetCode】哈希表 hash_table(共88题)

    [1]Two Sum (2018年11月9日,k-sum专题,算法群衍生题) 给了一个数组 nums, 和一个 target 数字,要求返回一个下标的 pair, 使得这两个元素相加等于 target ...

  5. 【LeetCode】树(共94题)

    [94]Binary Tree Inorder Traversal [95]Unique Binary Search Trees II (2018年11月14日,算法群) 给了一个 n,返回结点是 1 ...

  6. 【LeetCode】双指针 two_pointers(共47题)

    [3]Longest Substring Without Repeating Characters [11]Container With Most Water [15]3Sum (2019年2月26日 ...

  7. 【LeetCode】设计题 design(共38题)

    链接:https://leetcode.com/tag/design/ [146]LRU Cache [155]Min Stack [170]Two Sum III - Data structure ...

  8. 【LeetCode】堆 heap(共31题)

    链接:https://leetcode.com/tag/heap/ [23] Merge k Sorted Lists [215] Kth Largest Element in an Array (无 ...

  9. 【LeetCode】排序 sort(共20题)

    链接:https://leetcode.com/tag/sort/ [56]Merge Intervals (2019年1月26日,谷歌tag复习) 合并区间 Input: [[1,3],[2,6], ...

随机推荐

  1. 获取浏览区变化的方法resize() 方法

    当调整浏览器窗口的大小时,发生 resize 事件. resize() 方法触发 resize 事件,或规定当发生 resize 事件时运行的函数. <html> <head> ...

  2. Java数据结构与算法(2):栈

    栈是一种线性表,特点在于它只能在一个位置上进行插入和删除,该位置是表的末端,叫做栈的顶(top).因此栈是后进先出的(FIFO).栈的基本操作有push.peek.pop. 栈的示意图 进栈和出栈都只 ...

  3. scroll-view组件

    <scroll-view></scroll-view> 组件 这个组件的属性:(是要不说属性值,写不写都可以(建议不写)) scroll-x:允许横向滚动 (如果你设这个属性就 ...

  4. java设置RabbitMQ的消费处理出现:ConditionalRejectingErrorHandler : Execution of Rabbit message listener failed.

    WARN 7868 --- [cTaskExecutor-1] s.a.r.l.ConditionalRejectingErrorHandler : Execution of Rabbit messa ...

  5. 【服务器】一次对Close_Wait 状态故障的排查经历

    最近接连听说一台线上服务器总是不响应客户端请求. 登录服务器后查询iis状态,发现应用程序池状态变为已停止. 按经验想,重启后应该就ok,第一次遇到也确实起了作用,当时完全没在意,以为是其他人无意把服 ...

  6. SVN 客户端不显示图标解决方案

    下图为没有设置之前,文件夹不显示svn图标 SVN客户端不显示图标解决方案:右键svn->设置->图标覆盖->状态缓存选择"Windows外壳"->确定,刷 ...

  7. Delphi XE2 之 FireMonkey 入门(20) - TStyleBook(皮肤、样式相关)

    我觉得叫 "皮肤" 不如叫 "样式" 或 "风格", 因为它可以包含和动作关联的动画. 在 FMX 下, 控件可以任意绘制, 各部件个性化的 ...

  8. malloc函数分配内存失败的常见原因

    malloc()函数分配内存失败的常见原因:  1. 内存不足.  2. 在前面的程序中出现了内存的越界访问,导致malloc()分配函数所涉及的一些信息被破坏.下次再使用malloc()函数申请内存 ...

  9. Altium Designer chapter8总结

    元件库操作中需要注意如下: (1)原理图库:主要分三部分来完成(绘制元件的符号轮廓.放置元件引脚.设计规则检查). (2)多子件原理图库:操作与原理图库基本相同,就是新建part. (3)PCB封装库 ...

  10. Bootstrap 学习笔记 项目实战 首页内容介绍 下

    最终效果: HTML代码 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset ...