Open azl397985856 opened 3 years ago
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int l = 0;
int r = n;
while(l < r){
int mid = (r - l) / 2 + l;
if (isBadVersion(mid)){
r = mid;
}else{
l = mid + 1;
}
}
return r;
}
}
时间复杂度 O(logN) 空间复杂度 O(1)
二分法
var solution = function(isBadVersion) {
/**
* @param {integer} n Total versions
* @return {integer} The first bad version
*/
return function(n) {
let l=0,r=n,res=0;
while(l<=r){
let mid = Math.floor(l+(r-l)/2);
if(isBadVersion(mid)){
res = mid;
r = mid-1;
}else{
l = mid+1;
}
}
return res;
};
};
//二分
int firstBadVersion(int n) {
int left = 1, right = n;
while (left < right){
int mid = left + (right - left) / 2;
if (isBadVersion(mid) == true){
right = mid;
}
else {
left = mid + 1;
}
}
return right;
}
public class Solution extends VersionControl { public int firstBadVersion(int n) { int left = 0; int right = n; while(left < right){ int mid = (right - left) / 2 + left; if (isBadVersion(mid)){ right = mid; }else{ left = mid + 1; } } return right;
}
}
class Solution: def firstBadVersion(self, n): """ :type n: int :rtype: int """ left, right = 0, n-1 # index while left <= right: mid = (left+right)//2 if isBadVersion(mid): right = mid-1 else: left = mid +1
return left
搜索左侧边界的二分模板(搜索第一个满足isBadVersion() === true
) 的版本号。
var solution = function(isBadVersion) {
/**
* @param {integer} n Total versions
* @return {integer} The first bad version
*/
return function(n) {
let l = 1;
let r = n;
let mid;
while(l < r) {
mid = ((r - l) >> 1) + l;
if (isBadVersion(mid)) r = mid;
else l = mid + 1;
}
return l;
};
};
时间复杂度: O(logn)
额外空间复杂度: O(1)
二分
套用二分模板
搜索第一个满足 isBadVersion() === true 的版本号
/* The isBadVersion API is defined in the parent class VersionControl.
boolean isBadVersion(int version); */
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
//在0000011中找第一个1
// 左区间从1开始
int left = 1;
int right = n;
int mid = -1;
while(left < right) { //不能使用<=
mid = left + (right - left) / 2; //防止溢出
if(isBadVersion(mid) == true)
right = mid;
else
left = mid +1;
}
return left;
}
}
O(logn)
O(1)
title: "Day 38 278. 第一个错误的版本" date: 2021-10-17T19:30:01+08:00 tags: ["Leetcode", "c++", "Binary Search"] categories: ["91-day-algorithm"] draft: true
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。
你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
示例 1:
输入:n = 5, bad = 4
输出:4
解释:
调用 isBadVersion(3) -> false
调用 isBadVersion(5) -> true
调用 isBadVersion(4) -> true
所以,4 是第一个错误的版本。
示例 2:
输入:n = 1, bad = 1
输出:1
提示:
1 <= bad <= n <= 2^31 - 1
- 1、这里要注意,当API接口返回true时,不一定是找到了目标位置,还需要继续向前查找,直到找到第一个有问题的目标。
// The API isBadVersion is defined for you.
// bool isBadVersion(int version);
class Solution {
public:
int firstBadVersion(int n) {
int l = 1, r = n;
while(l < r)
{
int mid = l + (r - l) / 2;
if(isBadVersion(mid)) r = mid;
else l = mid + 1;
}
return l;
}
};
时间复杂度:O(logn)
空间复杂度:O(1)
var solution = function(isBadVersion) {
/**
* @param {integer} n Total versions
* @return {integer} The first bad version
*/
return function(n) {
let left = 1
let right = n
while(left <= right){
let mid = left + Math.floor((right - left) / 2)
if(isBadVersion(mid)){
right = mid-1
}else{
left = mid + 1
}
}
return left
};
};
二分
var solution = function (isBadVersion) {
return function (n) {
let left = 1;
let right = n;
while (left <= right) {
let mid = Math.floor((right + left) / 2);
if (isBadVersion(mid)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
};
};
https://leetcode-cn.com/problems/first-bad-version
二分法查找
# @lc code=start
# The isBadVersion API is already defined for you.
# @param version, an integer
# @return an integer
# def isBadVersion(version):
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
l = 0
r = n
while l<r:
mind = int((r-l)/2+l)
if isBadVersion(mind):
r = mind
else:
l = mind +1
return r
class Solution {
public:
int firstBadVersion(int n) {
int low = 1;
int max = n;
while(low<max){
int mid = low + (max - low)/2;
if(isBadVersion(mid)){
max = mid;
}else{
low = mid + 1;
}
}
return low;
}
};
Time:O(logn) Space:O(1)
278. 第一个错误的版本
https://leetcode-cn.com/problems/first-bad-version/
(1)如果发现isBadVersion(middle)是true说明在middle这个位置是错误版本,并且比middle大的版本数比对结果都是true,咱只需要比对low到middle这部分就好了,如果isBadVersion(middle)是false说明middle这个位置不是错误版本的开始,需要继续往大的找,需要在middle到high中找。 (2)我用的while是判断low<=high所以我在里面又加了一个if判断,不然当low=high会一直跳不出去,while函数结束后还返回了一个low,是检测个别结果,如只有一个版本。
class Solution:
def firstBadVersion(self, n):
low,high=0,n-1
while low<=high:
middle=int((low+high)/2)
if isBadVersion(middle):
high=middle
if low==high:
return low
else:
low=middle+1
return low
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int left = 0;
int right = n;
while (left < right) {
int mid = left + (right - left) / 2;
if (isBadVersion(mid)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
}
使用二分法
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
l=1
r=n
while l<r:
mid = l+(r-l)//2
if isBadVersion(mid):
r = mid
else:
l = mid+1
return l
时间复杂度: O(logn)
空间复杂度: O(1)
public class Solution extends VersionControl { public int firstBadVersion(int n) { int left = 1, right = n; while (left < right) { int mid = left + (right - left) / 2; if (isBadVersion(mid)) { right = mid; } else { left = mid + 1; } } return left; } }
var solution = function(isBadVersion) {
/**
* @param {integer} n Total versions
* @return {integer} The first bad version
*/
return function(n) {
var l = 1, r = n;
while (l <= r) {
var mid = Math.floor((l + r) / 2);
if (isBadVersion(mid)) {
r = mid - 1;
} else {
l = mid + 1;
}
}
return l;
};
};
时间:O(logn) 空间:O(1)
套用能力检测二分模板
# The isBadVersion API is already defined for you.
# @param version, an integer
# @return an integer
# def isBadVersion(version):
class Solution:
def firstBadVersion(self, n):
# 能力检测二分
left, right = 1, n
while left <= right:
mid = left + (right - left) // 2
if isBadVersion(mid) == True:
right = mid - 1
else:
left = mid + 1
return left
二分模板
func firstBadVersion(n int) int {
l,r := 0, n
for l <= r{
mid := l + (r-l)/2
if isBadVersion(mid) == true{
r =mid-1
}else{
l = mid+1
}
}
return l
}
时间复杂度:O(logN) 空间复杂度:O(1)
JavaScript Code:
/**
* Definition for isBadVersion()
*
* @param {integer} version number
* @return {boolean} whether the version is bad
* isBadVersion = function(version) {
* ...
* };
*/
/**
* @param {function} isBadVersion()
* @return {function}
*/
var solution = function(isBadVersion) {
/**
* @param {integer} n Total versions
* @return {integer} The first bad version
*/
return function(n) {
let l = 1;
let r = n;
while(l < r) {
let mid = l + parseInt((r - l) / 2);
if (!isBadVersion(mid)) {
l = mid + 1;
} else {
r = mid;
}
}
return l;
};
};
复杂度分析
令 n 为数组长度。
二分
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
l = 0
r = n -1
while l <= r:
mid = l + (r - l) // 2
if isBadVersion(mid):
r = mid - 1
else:
l = mid + 1
return l
时间复杂度:O(logN) 空间复杂度:O(1)
278. 第一个错误的版本
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/first-bad-version
前置知识
- 二分法
题目描述
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。 假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。 你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。 示例: 给定 n = 5,并且 version = 4 是第一个错误的版本。 调用 isBadVersion(3) -> false 调用 isBadVersion(5) -> true 调用 isBadVersion(4) -> true 所以,4 是第一个错误的版本。
解法:朴素二分就好了,如果mid没有问题,就继续mid+1,r之间检测
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
l=0
r=n
while l<=r:
mid=(l+r)//2
if not isBadVersion(mid):
l=mid+1
else:
r=mid-1
return l
时间复杂度:O(logN) 空间复杂度:O(1)
二分模版题。
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
left, right = 1, n
while left < right:
mid = left+(right-left)//2
if isBadVersion(mid):
right = mid
else:
left = mid + 1
return left
Time complexity: O(logN) Space complexity: O(1)
二分法从1到 n 进行搜索
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
start = 1
end = n
mid = 0
while start < end:
mid = start + ((end - start) >> 1)
if isBadVersion(mid):
end = mid
else:
start = mid + 1;
return start
C++ Code:
// The API isBadVersion is defined for you.
// bool isBadVersion(int version);
class Solution {
public:
int firstBadVersion(int n) {
int mid = 0;
int start = 1, end = n;
while (start + 1 < end) {
mid = start + (end - start) / 2;
if (isBadVersion(mid)) {
end = mid;
} else {
start = mid;
}
}
if (isBadVersion(start)) {
return start;
}
return end;
}
};
令 n 为输入参数。
/**
* Definition for isBadVersion()
*
* @param {integer} version number
* @return {boolean} whether the version is bad
* isBadVersion = function(version) {
* ...
* };
*/
/**
* @param {function} isBadVersion()
* @return {function}
*/
var solution = function (isBadVersion) {
/**
* @param {integer} n Total versions
* @return {integer} The first bad version
*/
return function (n) {
let l = 0
let r = n
while (l < r) {
const mid = Math.floor(l + (r - l) / 2);
if (!isBadVersion(mid)) l = mid + 1
else r = mid
}
return l
};
};
时间复杂度: O(log n)
空间复杂度: O(1)
二分法
java
int left = 0;
int right = n;
while(left <= right){
int mid = left + (right - left) / 2;
if(isBadVersion(mid)){
right = mid - 1;
}else{
left = mid + 1;
}
}
return left;
空间复杂度 O(log n) 时间复杂度 O(1)
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int left = 0;
int right = n;
while(left <= right){
int mid = left + (right - left) / 2;
if(isBadVersion(mid)){
right = mid - 1;
}else{
left = mid + 1;
}
}
return left;
}
二分
# The isBadVersion API is already defined for you.
# @param version, an integer
# @return an integer
# def isBadVersion(version):
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
l, r = 1, n
while l <= r:
mid = (l + r) // 2
if isBadVersion(mid):
r = mid - 1
else:
l = mid + 1
return r
时间复杂度:O(LogN)
空间复杂度:O(1)
/**
* Definition for isBadVersion()
*
* @param {integer} version number
* @return {boolean} whether the version is bad
* isBadVersion = function(version) {
* ...
* };
*/
/**
* @param {function} isBadVersion()
* @return {function}
*/
var solution = function (isBadVersion) {
/**
* @param {integer} n Total versions
* @return {integer} The first bad version
*/
return function (n) {
if (n === 1) return 1
let left = 1,
right = n,
middle
while (left <= right) {
middle = Math.floor((left + right) / 2)
if (isBadVersion(middle)) {
right = middle - 1
} else {
left = middle + 1
}
}
return left
}
}
var solution = function(isBadVersion) {
/**
* @param {integer} n Total versions
* @return {integer} The first bad version
*/
return function(n) {
let left=0,right=n;
while(left<right){
let mid=left+((right-left)>>1)
if(isBadVersion(mid)){
right=mid
}else{
left=mid+1;
}
}
return left;
};
};
二分查找最左边一个满足条件(badVersion)的值
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
l, r = 1, n
while l <= r:
mid = l + r >> 1
bad = isBadVersion(mid)
if bad:
r = mid-1
else:
l = mid+1
return l
Java Code:
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int left = 1, right = n; // [left, right]
while (left + 1 < right) {
int mid = left + (right - left) / 2;
if (isBadVersion(mid)) {
right = mid;
} else {
left = mid;
}
}
if (isBadVersion(left)) {
return left;
}
if (isBadVersion(right)) {
return right;
}
return -1;
}
}
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
left, right = 1, n
while left < right:
mid = left + (right - left) // 2
if isBadVersion(mid):
right = mid
else:
left = mid + 1
return left
time complexity: O(logn) space complexity: O(1)
public class Solution extends VersionControl { public int firstBadVersion(int n) { int left = 1, right = n; while (left < right) { int mid = left + (right - left) / 2; if (isBadVersion(mid)) { right = mid; } else { left = mid + 1; } }
return left;
}
}
二分、需要注意的是 r 需要等于 mid 、因为有可能 mid 也可能是、因为不能遗漏掉
var solution = function(isBadVersion) {
/**
* @param {integer} n Total versions
* @return {integer} The first bad version
*/
return function(n) {
let l = 1
let r = n
while(l<r){
let mid = l +((r-l)>>1)
if(isBadVersion(mid)){
r = mid
}else{
l = mid+1
}
}
return l
};
}
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int left = 1, right = n;
while (left < right) { // 循环直至区间左右端点相同
int mid = left + (right - left) / 2; // 防止计算时溢出
if (isBadVersion(mid)) {
right = mid; // 答案在区间 [left, mid] 中
} else {
left = mid + 1; // 答案在区间 [mid+1, right] 中
}
}
// 此时有 left == right,区间缩为一个点,即为答案
return left;
}
}
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int left = 0, right = n;
while(left <= right) {
int mid = left + (right - left) / 2;
if(!isBadVersion(mid)) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left;
}
}
Typical problem for finding the left boundary.
It is usually realized by [l,r) and the ending condition is l < r
as when l== r, there is no solution in the [r, r) range
It can also be realized by using [l, r], just pay attention that ending condition is l<=r
as no solution is at [r+1, r]
# The isBadVersion API is already defined for you.
# @param version, an integer
# @return an integer
# def isBadVersion(version):
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
left = 1
right = n
while left <= right:
mid = int(left + (right - left)/2)
if isBadVersion(mid):
right = mid - 1
else:
left = mid + 1
return left
二分法,找到最左边的错误版本。
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
l, r = 1, n
res = n
while l <= r:
m = ((r - l) >> 1) + l
if isBadVersion(m):
res = m
r = m - 1
else:
l = m + 1
return res
二分
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
left = 0
right = n-1
smallest_true = n
while left < right:
mid = (left + right) // 2
if isBadVersion(mid):
smallest_true = mid
right = mid - 1
else:
left = mid + 1
if isBadVersion(left):
smallest_true = left
return smallest_true
时间O(logn)
空间O(1)
Language: Java
class Solution extends VersionControl {
public int firstBadVersion(int n) {
int left = 0;
int right = n;
while (left <= right) {
int mid = left + (right - left) / 2;
if (isBadVersion(mid)) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return left;
}
}
二分法
JavaScript Code
var solution = function (isBadVersion) {
/**
* @param {integer} n Total versions
* @return {integer} The first bad version
*/
return function (n) {
let left = 1;
let right = n;
while (left <= right) {
let mid = Math.floor((right + left) / 2);
if (isBadVersion(mid)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
};
};
复杂度
套用二分法模板,但是忽略了溢出的问题,然后参考了官方解法中计算溢出的方法
语言:Java
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int i=1,j=n;
while(i<=j) {
int mid=i+(j-i)/2;
if(isBadVersion(mid)) {
j=mid-1;
}else {
i=mid+1;
}
}
return i;
}
}
var solution = function (isBadVersion) { /**
@return {integer} The first bad version */ return function (n) { let left = 1; let right = n;
while (left <= right) { let mid = Math.floor((right + left) / 2);
if (isBadVersion(mid)) { right = mid; } else { left = mid + 1; } }
return left; }; };
题解方法二分法
class Solution:
def firstBadVersion(self, n):
l, r = 1, n
while l <= r:
mid = (l + r) // 2
if isBadVersion(mid):
# 收缩
r = mid - 1
else:
l = mid + 1
return l
复杂度分析
public class Solution extends VersionControl { public int firstBadVersion(int n) { int left = 0, right = n; while(left <= right) { int mid = left + (right - left) / 2; if(!isBadVersion(mid)) { left = mid + 1; } else { right = mid - 1; } } return left; } }
278. 第一个错误的版本 - 力扣(LeetCode) (leetcode-cn.com)
/* The isBadVersion API is defined in the parent class VersionControl.
boolean isBadVersion(int version); */
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int left = 1;
int right = n;
while(left <= right){
int mid = left + (right - left) / 2;
if(isBadVersion(mid)){
right = mid - 1;
}else{
left = mid + 1;
}
}
return left;
}
}
# The isBadVersion API is already defined for you.
# @param version, an integer
# @return an integer
# def isBadVersion(version):
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
left = 1
right = n
while left <= right:
mid = left + (right-left)//2
if isBadVersion(mid) == 1:
right = mid - 1
else:
left = mid + 1
return left
Time: O(logN)
Space: O(1)
二分法查找左边第一个满足条件的值。
/* The isBadVersion API is defined in the parent class VersionControl.
boolean isBadVersion(int version); */
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int start = 0, end = n;
while (start <= end){
int mid = start + (end - start) / 2;
if (isBadVersion(mid)){
end = mid - 1;
} else {
start = mid + 1;
}
}
return start;
}
}
278. 第一个错误的版本
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/first-bad-version
前置知识
题目描述
假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。
你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
示例:
给定 n = 5,并且 version = 4 是第一个错误的版本。
调用 isBadVersion(3) -> false 调用 isBadVersion(5) -> true 调用 isBadVersion(4) -> true
所以,4 是第一个错误的版本。