LeetCode--二分查找相关算法
-(1)有一个升序排列的非负数组,要求利用o(logn)的时间复杂度找到数组中确定数字target的第一次出现的位置下标和最后一次出现的位置下标,如果不存在该target返回[-1,-1]
解决方案:本题是考察二分查找算法,通过两次二分查找算法找到target的起始下标和终止下标,放在一个数组中返回
public int[] findFirstAndLastIndex(int[] nums,int target){
int[] res = new int[]{-1,-1};
if(nums==null || nums.length<=1||target<0)
return res;
res[0]=findFirst(nums,target);
res[1]=findLast(nums,target);
return res;
}
public int findFirst(int[] nums,int target){
int idx=-1;
int start=0,end=nums.length-1,mid=0;
while(start<=end){
mid=start+(end-start)/2;
if(nums[mid]>=target)
end=mid-1;
else
start=mid+1;
if(nums[mid]==target)
idx=mid;
}
return idx;
}
public int findLast(int[] nums,int target){
int idx=-1;
int start=0,end=nums.length-1,mid=0;
while(start<=end){
mid=start+(end-start)/2;
if(nums[mid]<=target)
start=mid+1;
else
end=mid-1;
if(nums[mid]==target)
idx=mid;
}
return idx;
}
(2) 每一个app开发出来后,我们需要定期的对其进行更新(不管是升级还是修改bug),假设app当前已有n个版本,如果某一个版本出现错误,那么从这个版本开始后面的版本全部会出错,要求我们找出第一个出现错误的版本
解决方案:还是二分查找,当我们当前的mid对于的版本是错误版本(假设给定一个函数isError(viersion),true为错误版本,flase为正确版本),我们就往mid的左半部分找到初始错误版本,否则,就往mid右半部分找到初始错误版本
public int findFirstErrorVersion(int n){
int start=1,end=n,mid=1;
while(start<end){
mid=start+(end-start)/2;//为什么不是mid=(start+end)/2
if(!isError(mid))
start=mid+1;
else
end=mid;
}
return start;
}
接下来,我解释一下上面的一个问题,为什么不能写成mid=(start+end)/2,因为,start,end均为整型数据,int型数据的最大值为2147483647,假如这里n=Integer.MAX_VALUE ,start=Integer.MAX_VALUE-1,end=Integer.MAX_VALUE,那么此时,(start+end)必须超过整型数据的返回,自然会出现问题,所以,一般情况下,最好还是写成start+(end-start)/2形式,何乐而不为呢?
补加:
Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead.
For example, given the array [2,3,1,2,4,3]
and s = 7
,
the subarray [4,3]
has the minimal length under the problem constraint.
private int solveNLogN(int s, int[] nums) {
int[] sums = new int[nums.length + 1];
for (int i = 1; i < sums.length; i++) sums[i] = sums[i - 1] + nums[i - 1];
int minLen = Integer.MAX_VALUE;
for (int i = 0; i < sums.length; i++) {
int end = binarySearch(i + 1, sums.length - 1, sums[i] + s, sums);
if (end == sums.length) break;
if (end - i < minLen) minLen = end - i;
}
return minLen == Integer.MAX_VALUE ? 0 : minLen;
} private int binarySearch(int lo, int hi, int key, int[] sums) {
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (sums[mid] >= key){
hi = mid - 1;
} else {
lo = mid + 1;
}
}
return lo;
}
}
LeetCode--二分查找相关算法的更多相关文章
- leetcode二分查找相关
目录 33/81搜索旋转排序数组 34在排序数组中查找元素的第一个和最后一个位置 35搜索插入位置 74搜索二维矩阵 300最长上升子序列,354俄罗斯套娃信封问题 33/81搜索旋转排序数组 假设按 ...
- leetcode二分查找问题整理
自从做完leetcode上的三道关于二分查找的题后,我觉得它是比链表找环还恶心的题,首先能写出bugfree代码的人就不多,而且可以有各种变形,适合面试的时候不断挑战面试者,一个程序猿写代码解决问题的 ...
- leetcode 二分查找
https://oj.leetcode.com/problems/search-for-a-range/就是一个二分查找,没事练练手 public class Solution { public in ...
- Leetcode 二分查找 Search Insert Position
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie Search Insert Position Total Accepted: 14279 T ...
- [leetcode]二分查找总结
Search for a Range 1.最简单的想法,用最普通的二分查找,找到target,然后向左右扩张,大量的重复的target,就会出现O(n)效率. class Solution { pub ...
- leetcode 二分查找 Search in Rotated Sorted ArrayII
Search in Rotated Sorted Array II Total Accepted: 18500 Total Submissions: 59945My Submissions Follo ...
- leetcode 二分查找 Search in Rotated Sorted Array
Search in Rotated Sorted Array Total Accepted: 28132 Total Submissions: 98526My Submissions Suppose ...
- LeetCode 二分查找模板 II
模板 #2: int binarySearch(vector<int>& nums, int target){ if(nums.size() == 0) return -1; in ...
- LeetCode 二分查找模板 I
模板 #1: int binarySearch(vector<int>& nums, int target){ if(nums.size() == 0) return -1; in ...
随机推荐
- 简述UML类图
注:本文摘自刘伟老师的博客http://blog.csdn.net/lovelion/article/details/7838679,如有侵权,请联系本人! 1.类的UML图示 在UML中,类使用包含 ...
- Spring Boot :Druid Monitor
忙里偷个闲,在这里分享一下SpringBoot集成Druid实现数据库监控功能,有什么错误欢迎大家指出! 参考文件: Spring实现Druid监控:https://www.cnblogs.com/w ...
- EJB2.0版本的HelloWorld
EJB2.0版本的HelloWorld 虽然EJB3.1已经出来了,可是EJB2.0的项目还需要维护啊.下面写个简单EJB2.0的HelloWorld程序,练练手. 环境: JBoss 4.0 ...
- codeforces Gym 100338F Spam Filter 垃圾邮件过滤器(模拟,实现)
阅读题, 概要:给出垃圾邮件和非垃圾邮件的集合,然后按照题目给出的贝叶斯公式计算概率一封邮件是垃圾邮件的概率. 逐个单词判断,将公式化简一下就是在垃圾邮件中出现的次数和在总次数的比值,大于二分之一就算 ...
- Resize a UIImage the right way
When deadlines loom, even skilled and experienced programmers can get a little sloppy. The pressure ...
- k8s学习目录
目录 K8S基础部分 基础部分 5 秒创建 k8s 集群[转] k8s 核心功能[转] k8s 重要概念[转] 部署 k8s Cluster(上)[转] 部署 k8s Cluster(下)[转] Ku ...
- CPP-基础:cout
C++编程语言互换流中的标准输出流,需要iostream.h支持.读为 "c out". 使用范例 //用户输入的数字由cin保存于变量a中,并通过cout输出. #include ...
- OpenCV2:介绍
一.OpenCV简介 OpenCV所有的类和函数都在cv命名空间里面,可以用 using namespace cv; #include "opencv2/opencv.hpp" 1 ...
- 【离线做法 树状数组】luoguP1972 [SDOI2009]HH的项链
与bzoj3585: mex的线段树做法有着异曲同工之妙 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...
- 【分块】[HNOI2010]弹飞绵羊&分块大法祭
分块(似乎还有一种动态树(LCT)做法) 第一次学习分块,似乎有点小激动 这是黄学长的分块入门博客「分块」数列分块入门1 – 9 by hzwer 题目描述 某天,Lostmonkey发明了一种超级弹 ...