LeetCode总结--二分查找篇
二分查找算法尽管简单,但面试中也比較常见。经经常使用来在有序的数列查找某个特定的位置。在LeetCode用到此算法的主要题目有:
Search
Insert Position
Search
for a Range
Sqrt(x)
Search
a 2D Matrix
Search
in Rotated Sorted Array
Search
in Rotated Sorted Array II
这类题目基本能够分为例如以下四种题型:
1. Search
Insert Position和Search
for a Range是考察二分查找的基本使用方法。基本思路是每次取中间,假设等于目标即返回,否则依据大小关系切去一半,因此时间复杂度是O(logn),空间复杂度O(1)。
以Search
Insert Position为例,其关键代码写法例如以下:
int l = 0;
int r = A.length-1;
while(l<=r)
{
int mid = (l+r)/2;
if(A[mid]==target)
return mid;
if(A[mid]<target)
l = mid+1;
else
r = mid-1;
}
return l;
这样当循环停下来时,假设不是正好找到target,l指向的元素恰好大于target。r指向的元素恰好小于target,这里l和r可能越界。只是假设越界就说明大于(小于)target而且是最大(最小)。Search
for a Range这道题能更好的解释这一点。
其思路是先用二分查找找到当中一个target。然后再往左右找到target的边缘。我们主要看找边缘(往后找)的代码:
int newL = m;
int newR = A.length-1;
while(newL<=newR)
{
int newM=(newL+newR)/2;
if(A[newM]==target)
{
newL = newM+1;
}
else
{
newR = newM-1;
}
}
res[1]=newR;
public int sqrt(int x) {
if(x<0) return -1;
if(x==0) return 0;
int l=1;
int r=x/2+1;
while(l<=r)
{
int m = (l+r)/2;
if(m<=x/m && x/(m+1)<m+1)
return m;
if(x/m<m)
{
r = m-1;
}
else
{
l = m+1;
}
}
return 0;
}
这里要注意,这里推断相等的条件不是简单的 m == x/m, 而是 m<=x/m && x/(m+1)<m+1, 这是由于输出是整型。sqrt(14)=3 但 3 != 14/3. 所以我们须要一个范围框住结果。另外依据二分查找算法的特性,假设不能正好m==x/m停下,那么r指向的数字将正好是结果取整的值。
所以我们也能够这样写:
public int sqrt(int x) {
if(x<0) return -1;
if(x==0) return 0;
int l=1;
int r=x/2+1;
while(l<=r)
{
int m = (l+r)/2;
if(m==x/m )
return m;
if(x/m<m)
{
r = m-1;
}
else
{
l = m+1;
}
}
return r;
}
4. Search in Rotated Sorted Array和Search
in Rotated Sorted Array II算是二分查找算法的一个变体。
在Search in Rotated Sorted Array中,乍一看感觉数组已经不是有序的了。也就无法用二分查找算法,但细致分析一下会发现,由于仅仅rotate了一次,如果二分一下,总有一半是有序的,并且和还有一半无区间重叠,我们仅仅须要检查有序的一半的前后两个元素就能够确定target可能在哪一半。详细来说,如果数组是A,每次左边缘为l,右边缘为r。还有中间位置是m。
在每次迭代中,分三种情况:
(1)假设target==A[m],那么m就是我们要的结果,直接返回;
(2)假设A[m]<A[r]。那么说明从m到r一定是有序的(没有受到rotate的影响),那么我们仅仅须要推断target是不是在m到r之间,假设是则把左边缘移到m+1,否则就target在还有一半,即把右边缘移到m-1。
(3)假设A[m]>=A[r]。那么说明从l到m一定是有序的,相同仅仅须要推断target是否在这个范围内,对应的移动边缘就可以。
依据以上方法,每次我们都能够切掉一半的数据。所以算法的时间复杂度是O(logn),空间复杂度是O(1)。
所以最坏情况(比方所有都是一个元素。或者仅仅有一个元素不同于其它元素,而他就在最后一个)就会出现每次移动一步,总共是n步,算法的时间复杂度变成O(n)。
整体来说。二分查找算法理解起来并不算难。但在实际面试的过程中可能会出现各种变体,怎样灵活的运用才是制胜的关键。
我们要抓住“有序”的特点。一旦发现输入有“有序”的特点,我们就能够考虑能否够运用二分查找算法来解决该问题。
LeetCode总结--二分查找篇的更多相关文章
- LeetCode 704. 二分查找(Binary Search)
704. 二分查找 704. Binary Search 题目描述 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target,写一个函数搜索 nums 中的 target,如果 ...
- 【LeetCode】二分查找
给一个升序数组,找到目标值在数组中的起始和结束位置,时间复杂度为 O(log n). e.g. 给定数组 [5, 7, 7, 8, 8, 10] 和目标值 8,返回 [3, 4].若目标值不在数组中, ...
- Java实现 LeetCode 704 二分查找(二分法)
704. 二分查找 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1. 示例 1 ...
- LeetCode 704.二分查找(C++)
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1. 示例 1: 输入: num ...
- LeetCode 704. 二分查找
题目链接:https://leetcode-cn.com/problems/binary-search/ 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函 ...
- leetcode中二分查找的具体应用
给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是 O(log n) 级别. 如果数组中不存在目标值,返回 [ ...
- C#LeetCode刷题-二分查找
二分查找篇 # 题名 刷题 通过率 难度 4 两个排序数组的中位数 C#LeetCode刷题之#4-两个排序数组的中位数(Median of Two Sorted Arrays)-该题未达最优解 30 ...
- 分治算法(二分查找)、STL函数库的应用第五弹——二分函数
分治算法:二分查找!昨天刚说不写算法了,但是突然想起来没写过分治算法的博客,所以强迫症的我…… STL函数库第五弹——二分函数lower_bound().upper_bound().binary_se ...
- LeetCode刷题总结-二分查找和贪心法篇
本文介绍LeetCode上有关二分查找和贪心法的算法题,推荐刷题总数为16道.具体考点归纳如下: 一.二分查找 1.数学问题 题号:29. 两数相除,难度中等 题号:668. 乘法表中第k小的数,难度 ...
随机推荐
- 最优化方法系列:Adam+SGD—>AMSGrad
自动调参的Adam方法已经非常给力了,不过这主要流行于工程界,在大多数科学实验室中,模型调参依然使用了传统的SGD方法,在SGD基础上增加各类学习率的主动控制,以达到对复杂模型的精细调参,以达到刷出最 ...
- 09Oracle Database 数据表数据插入,更新,删除
Oracle Database 数据表数据插入,更新,删除 插入数据 Insert into table_name(column) values(values); insert into studen ...
- 字符串--P1553 数字反转(升级版)
题目描述 给定一个数,请将该数各个位上数字反转得到一个新数. 这次与NOIp2011普及组第一题不同的是:这个数可以是小数,分数,百分数,整数.整数反转是将所有数位对调:小数反转是把整数部分的数反转, ...
- UVA-227 Puzzle(模拟)
题目: 题目浏览传送门 题意: 给出一个5*5的方格,里边有一个格子是空的,现在给出一串指令,A->空格向上移动,B->空格向下移动,R->空格向右移动,L->空格向左移动. ...
- [POJ1155]TELE(树形背包dp)
看到这道题的第一眼我把题目看成了TLE 哦那不是重点 这道题是树形背包dp的经典例题 题目描述(大概的): 给你一棵树,每条边有一个cost,每个叶节点有一个earn 要求在earn的和大于等于cos ...
- Object类型转换为String类型
1. Object.toString() 1 obj.toString() 注意:必须保证Object不是null值,否则将抛出NullPointerException异常. 2. (String)O ...
- Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'.
在连接数据库时,使用了最新版本的mysql-Connector,所以导致老版本的“com.mysql.jdbc.Drive”不可行,要改为“com.mysql.cj.jdbc.Driver”
- 【eclipse】外部 jar 包导入教程
JavaWeb 项目中,可以直接将要导入的 jar 程序包复制到你项目下的 WEB-INF/lib 文件夹下,将来程序移动到别的机子上测试时也能正常运行.如果是普通 Java 工程的话,我们可以在项目 ...
- uWSGI+nginx+django+virtualenv+supervisor部署项目
一.前言 在部署项目前,你已有一个能够在你本机测试过,能正常启动的Django项目(毕竟本文主要讲解部署Django项目),以及掌握了Linux系统的一些基本命令. 相关链接: Centos7安装py ...
- Leetcode题目practice
目录 Leetcode题目解答 1. 删除最外层的括号 2. 两数之和 3. 宝石与石头 4. 移除元素 5.删除排序数组中的重复项 6.寻找两个有序数组的中位数 7.盛最多水的容器 8.存在重复元素 ...