二分法模板

非递归版本:

 public class Solution {
/**
* @param A an integer array sorted in ascending order
* @param target an integer
* @return an integer
*/
public int findPosition(int[] nums, int target) {
if (nums == null || nums.length == 0) {
return -1;
} int start = 0, end = nums.length - 1;
// 要点1: start + 1 < end
while (start + 1 < end) {
// 要点2:start + (end - start) / 2
int mid = start + (end - start) / 2;
// 要点3:=, <, > 分开讨论,mid 不+1也不-1
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
start = mid;
} else {
end = mid;
}
} // 要点4: 循环结束后,单独处理start和end
if (nums[start] == target) {
return start;
}
if (nums[end] == target) {
return end;
}
return -1;
}
}

死循环的发生:when target is the last position of the range
nums = [1,1], target = 1
使用 start < end 无论如何都会出现死循环

递归版本:

 public class Solution{
public int findPosition(int[] nums, int target){
return binarySearch(nums, 0, nums.length-1, target);
} public int binarySearch(int[] nums, int start, int end, int target){
if(start>end)
return(-1); int mid=(start+end)/2;
if(nums[mid]==target)
return(mid);
if(nums[mid]<target)
return binarySearch(nums, mid+1, end, target);
else
return binarySearch(nums, start, mid-1, target);
}
}

常见问题

Q: 为什么要用 start + 1 < end?而不是 start < end 或者 start <= end?

A: 为了避免死循环。二分法的模板中,整个程序架构分为两个部分:

  1. 通过 while 循环,将区间范围从 n 缩小到 2 (只有 start 和 end 两个点)。
  2. 在 start 和 end 中判断是否有解。

start < end 或者 start <= end 在寻找目标最后一次出现的位置的时候,出现死循环。

Q: 为什么明明可以 start = mid + 1 偏偏要写成 start = mid?

A: 大部分时候,mid 是可以 +1 和 -1 的。在一些特殊情况下,比如寻找目标的最后一次出现的位置时,当 target 与 nums[mid] 相等的时候,是不能够使用 mid + 1 或者 mid - 1 的。因为会导致漏掉解。那么为了节省脑力,统一写成 start = mid / end = mid 并不会造成任何解的丢失,并且也不会损失效率——log(n) 和 log(n+1) 没有区别。


许多同学在写二分法的时候,都比较习惯性的写 while (start < end) 这样的循环条件。这样的写法及其容易出现死循环,导致 LintCode 上的测试“超时”(Time Limit Exceeded)。

什么情况下会出现死循环?

在做 last position of target 这种模型下的二分法时,使用 while (start < end) 就容易出现超时。

在线练习:http://www.lintcode.com/problem/last-position-of-target/

我们来看看会超时的代码:
Java版本:

int start = 0, end = nums.length - 1;
while (start < end) {
int mid = start + (end - start) / 2;
if (nums[mid] == target) {
start = mid;
} else if (nums[mid] < target) {
start = mid + 1;
} else {
end = mid - 1;
}
}

上面这份代码是大部分同学的实现方式。看上去似乎没有太大问题。我们来注意一下 `nums[mid] == target` 时候的处理。这个时候,因为 mid 这个位置上的数有可能是最后一个出现的target,所以不能写成 start = mid + 1(那样就跳过了正确解)。而如果是这样写的话,下面这组数据将出现超时(TLE):

nums = [1,1], target = 1

将数据带入过一下代码:

start = 0, end = 1
while (0 < 1) {
    
mid = 0 + (1 - 0) / 2 = 0
    
if (nums[0] == 1) {
        
start = 0;
    
}
    
...
}

我们发现,start 将始终是 `0`。

出现这个问题的主要原因是,mid = start + (end - start) / 2 这种写法是偏向start的。也就是说 mid 是中间偏左的位置。这样导致如果 start 和 end 已经是相邻关系,会导致 start 有可能在一轮循环之后保持不变。

或许你会说,那么我改成 mid = (start + end + 1) / 2 是否能解决问题呢?没错,确实可以解决 last position of target 的问题,但是这样之后 first position of target 就超时了。我们比较希望能够有一个理想的模板,无论是 first position of target 还是 last position of target,代码的区别尽可能的小和容易记住。


类型1:裸题

704. Binary Search

 class Solution:
def bd(self, nums, target, start, end):
while(start+1<end):
mid=(start+end)//2
if(nums[mid]==target):
return mid
if(nums[mid]>target):
end=mid
if(nums[mid]<target):
start=mid
if(nums[start]==target):
return start
if(nums[end]==target):
return end
return -1 def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
sl=len(nums)-1
if(sl==-1):
return -1
ans=self.bd(nums, target, 0, sl)
return ans
 class Solution {
public int search(int[] nums, int target) {
int start=0, end=nums.length-1;
while(start+1<end){
int mid=start+(end-start)/2;
if(nums[mid]==target)
return mid;
if(nums[mid]<target)
start=mid;
if(nums[mid]>target)
end=mid;
}
if(nums[end]==target)
return(end);
if(nums[start]==target)
return(start); return(-1);
}
}

34. Find First and Last Position of Element in Sorted Array

其实稍微改改边界就行了,但是写起来坑很多....

 class Solution:
def fbs(self, nums, target, start, end):
tmp=999999
while(start+1<end):
mid=(start+end)//2
if(nums[mid]==target):
tmp=mid
end=mid
if(nums[mid]>target):
end=mid
if(nums[mid]<target):
start=mid
if(nums[start]==target):
tmp=min(tmp,start)
if(nums[end]==target):
tmp=min(tmp, end)
if(tmp==999999):
return -1
else:
return tmp def lbs(self, nums, target, start, end):
tmp=-1
while(start+1<end):
mid=(start+end)//2
if(nums[mid]==target):
tmp=mid
start=mid
if(nums[mid]>target):
end=mid
if(nums[mid]<target):
start=mid
if(nums[start]==target):
tmp=max(tmp,start)
if(nums[end]==target):
tmp=max(tmp, end)
return tmp def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if(len(nums)==0):
return([-1,-1])
fs=self.fbs(nums, target, 0, len(nums)-1)
ls=self.lbs(nums, target, 0, len(nums)-1)
return([fs, ls])
 class Solution {
public int[] searchRange(int[] nums, int target) {
int start, end, mid;
int[] ans=new int[];
ans[]=-; ans[]=-;
if(nums.length==)
return(ans); start=; end=nums.length-;
while(start+<end){
mid=(start+end)/;
if(nums[mid]==target)
ans[]=mid;
if(nums[mid]>=target)
end=mid;
if(nums[mid]<target)
start=mid;
}
if(nums[start]!=target && nums[end]!=target && ans[]==-)
return(ans);
if(nums[end]==target)
ans[]=end;
if(nums[start]==target)
ans[]=start; start=; end=nums.length-;
while(start+<end){
mid=(start+end)/;
if(nums[mid]==target)
ans[]=mid;
if(nums[mid]>target)
end=mid;
if(nums[mid]<=target)
start=mid;
}
if(nums[start]==target)
ans[]=Math.max(ans[], start);
if(nums[end]==target)
ans[]=Math.max(ans[], end); return(ans);
}
} 注意几个极端数据:
[,]
[]
[,]
[,,]

类型2:OOXX
给定一个数组(数据类似OOOOOOXXXXXXXXX),求数组中第一个/最后一个满足某个条件(X)的位置

278. First Bad Version

还是用二分法,把条件魔改一下就行了

改成while(start<end)是为了不漏掉剩余区间长度为2的情况。同时为了防止死循环,start也得改成mid+1

 # The isBadVersion API is already defined for you.
# @param version, an integer
# @return a bool
# def isBadVersion(version): class Solution:
def bs(self, start, end):
cnt=0
while(start<end):
mid=(start+end)//2
cnt+=1
print(start,end,mid,cnt)
if(isBadVersion(mid)):
end=mid
else:
start=mid+1
return start def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
if(n<=1):
return n
return self.bs(1,n)

还用原来的二分模板也可以....但要注意mid=start+(end-start)/2,防止溢出

 /* 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=1,end=n,mid=-1; while(start+1<end){
mid=start+(end-start)/2;
if(isBadVersion(mid))
end=mid;
else
start=mid;
}
if(isBadVersion(start))
return(start);
if(isBadVersion(end))
return(end);
return(mid);
}
}

658. Find K Closest Elements

先用二分找到数组内离target最近的元素下标,然后用O(k)的时间,用两个指针从中间向外扩展再找离得最近的k-1个元素即可。最后排个序输出

 class Solution:
def bs(self, x, arr, start, end):
while (start+1<end):
mid=(start+end)//2
if(arr[mid]==x):
return mid
if(arr[mid]<x):
start=mid
if(arr[mid]>x):
end=mid
ansx=abs(arr[start]-x)
ans=start
while (ans<end and abs(arr[ans+1]-x)<ansx):
ans+=1
ansx=abs(arr[ans]-x)
return ans def findClosestElements(self, arr, k, x):
"""
:type arr: List[int]
:type k: int
:type x: int
:rtype: List[int]
"""
pos=self.bs(x, arr, 0, len(arr)-1)
print(pos)
pl=pos-1
pr=pos+1
tk=k-1
ans=[arr[pos]]
while(tk):
if(pl<0 and pr<=len(arr)-1):
ans.append(arr[pr])
pr+=1
if(pl>=0 and pr>len(arr)-1):
ans.append(arr[pl])
pl-=1
if(pl>=0 and pr<=len(arr)-1):
if(abs(arr[pr]-x)<abs(arr[pl]-x)):
ans.append(arr[pr])
pr+=1
else:
ans.append(arr[pl])
pl-=1
tk-=1
ans.sort()
return ans sl=Solution()
aa=[0,0,0,1,3,5,6,7,8,8]
print(sl.findClosestElements(aa,2,2))
 class Solution {
public List<Integer> findClosestElements(int[] arr, int k, int x) {
List<Integer> ans=new ArrayList<>();
int start=0,end=arr.length-1,mid=-1;
boolean found=false;
while(start+1<end){
mid=start+(end-start)/2;
if(arr[mid]==x){
found=true;
break;
}
if(arr[mid]<x)
start=mid;
if(arr[mid]>x)
end=mid;
}
if(arr[start]==x){
found=true;
mid=start;
}
if(arr[end]==x){
found=true;
mid=end;
}
if(!found){
if(x>arr[arr.length-1])
mid=end;
else if(x<arr[0])
mid=start;
else{
if(x-arr[start]<=arr[end]-x)
mid=start;
else
mid=end;
}
}
System.out.println(mid); ans.add(arr[mid]);
int pl=mid-1,pr=mid+1,cnt=0;
while(cnt<k-1){
if(pl<0){
ans.add(arr[pr]);
pr++;
}
else if(pr>=arr.length){
ans.add(arr[pl]);
pl--;
}
else if(x-arr[pl]<=arr[pr]-x){
ans.add(arr[pl]);
pl--;
}
else{
ans.add(arr[pr]);
pr++;
}
cnt++;
}
Collections.sort(ans);
return(ans);
}
}

852. Peak Index in a Mountain Array

ooooPxxxxx题,一样的套路

o: 单调递增 x: 单调递减

注意处理mid正好是peak的情况

 class Solution:
def peakIndexInMountainArray(self, A):
"""
:type A: List[int]
:rtype: int
"""
la=len(A)
start=0
end=la-1
while(start+1<end):
mid=(start+end)//2
if(A[mid-1]<A[mid] and A[mid]>A[mid+1]):
return mid
if(A[mid-1]<A[mid] and A[mid]<A[mid+1]):
start=mid
if(A[mid-1]>A[mid] and A[mid]>A[mid+1]):
end=mid
return (start if A[start]>A[end] else end)
 class Solution {
public int peakIndexInMountainArray(int[] A) {
int start=0,end=A.length,mid;
while(start+1<end){
mid=start+(end-start)/2;
if(A[mid-1]<A[mid] && A[mid]>A[mid+1])
return(mid);
if(A[mid-1]<A[mid] && A[mid]<A[mid+1])
start=mid;
if(A[mid-1]>A[mid] && A[mid]>A[mid+1])
end=mid;
}
if(start>0 && (A[start-1]<A[start] && A[start]>A[start+1]))
return(start);
if(end<A.length-1 && (A[end-1]<A[end] && A[end]>A[end+1]))
return(end);
return(-1);
}
}

74. Search a 2D Matrix

二分两遍。第一遍找在哪一行,第二遍找具体的value

第一遍找哪一行的时候,注意对最后剩下的start和end的判断。我的理解是二分查找的while搜完之后start和end会正好卡在距离target最近的值左右。(要么是A[start]<=target && A[end]>=target,要么是A[start]>=target,要么是A[end]<=target,分别想一下即可)

 class Solution:
def bs(self, nums, _start, _end, target, R):
start=_start
end=_end
while(start+1<end):
mid=(start+end)//2
if(nums[mid]>target):
end=mid
if(nums[mid]<target):
start=mid
if(nums[mid]==target):
return mid
if(R==1): #search for value
if(nums[start]==target):
return start
if(nums[end]==target):
return end
return -1
if(R==0): #search for range
if(nums[start]<=target and nums[end]>target):
return start
if(nums[end]<=target):
return end
else:
return -1 def searchMatrix(self, mm, target):
"""
:type mm: List[List[int]]
:type target: int
:rtype: bool
"""
if(len(mm)==0):
return False
ml=len(mm[0])
if(ml==0):
return False
fst=[xx[0] for xx in mm]
rg=self.bs(fst,0,len(fst)-1,target,0)
print(rg)
ans=self.bs(mm[rg],0,ml-1,target,1)
if(ans==-1):
return False
else:
return True sl=Solution()
mm=[[5,6,7,8]]
print(sl.searchMatrix(mm,8))
 class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int start,end,mid,idx;
int lx=matrix.length;
if(lx==0) return(false);
int ly=matrix[0].length;
if(ly==0) return(false); start=0; end=lx-1;
while(start+1<end){
mid=(start+end)/2;
if(matrix[mid][0]==target)
return(true);
if(matrix[mid][0]<target)
start=mid;
if(matrix[mid][0]>target)
end=mid;
}
if(matrix[start][0]>target)
return(false);
if(matrix[end][0]<=target)
idx=end;
else
idx=start; start=0; end=ly-1;
while(start+1<end){
mid=(start+end)/2;
if(matrix[idx][mid]==target)
return(true);
if(matrix[idx][mid]<target)
start=mid;
if(matrix[idx][mid]>target)
end=mid;
}
if(matrix[idx][start]==target || matrix[idx][end]==target)
return(true);
else
return(false);
}
}

240. Search a 2D Matrix II

这题其实不是二分....

O(M+N)的方法:类似dp一样转移当前位置

[i][j] -> [i][j+1] , if A[i][j]<target
[i-1][j] , if A[i][j]>target

初始放在最左下角,即[len(A)-1][0]处

 class Solution:
def searchMatrix(self, matrix, target):
"""
:type matrix: List[List[int]]
:type target: int
:rtype: bool
"""
lm=len(matrix)
if(lm==0):
return False
ln=len(matrix[0])
if(ln==0):
return False tx=lm-1
ty=0
for i in range(0,lm+ln):
if(tx<0 or ty>=ln):
return False
tmp=matrix[tx][ty]
#print(tx,ty,tmp)
if(tmp==target):
return True
if(tmp>target):
tx-=1
if(tmp<target):
ty+=1 sl=Solution()
sl.searchMatrix([[1]],1)
 class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int lx=matrix.length-1;
if(lx<0) return(false);
int ly=matrix[0].length-1;
if(ly<0) return(false); int px=lx,py=0;
while(px>=0 && py<=ly){
if(px>0 && matrix[px][py]>target)
px-=1;
else if(matrix[px][py]==target)
return(true);
else if(py<ly && matrix[px][py]<target)
py+=1;
else
return(false);
}
return(false);
}
}

https://www.lintcode.com/problem/search-for-a-range/description

同LeetCode 34. Find First and Last Position of Element in Sorted Array ,   往上滑滚动条就有......

https://www.lintcode.com/problem/total-occurrence-of-target/

没权限呜呜呜...

302 Smallest Rectangle Enclosing Black Pixels

传送门:https://www.lintcode.com/problem/smallest-rectangle-enclosing-black-pixels/description

类型3:

162. Find Peak Element

看似一头雾水,其实yy一下就行了...

因为左端和右端都是负无穷,所以peak肯定是存在的。然后在二分法中,因为mid肯定是夹在start和end中间的,所以直接讨论4种情况:

  • nums[mid-1]<nums[mid]>nums[mid+1]  直接输出完事了
  • nums[mid-1]<nums[mid]<nums[mid+1]  start:=mid,去找右边那个peak
  • nums[mid-1]>nums[mid]>nums[mid+1]  end:=mid,去找左边那个peak
  • nums[mid-1]>nums[mid]<nums[mid+1]  两边都有peak,随便start:=mid或者end:=mid都可以
 class Solution {
public int findPeakElement(int[] nums) {
if(nums.length==1)
return(0); int l=0,r=nums.length-1,mid=-1;
while(l+1<r){
mid=l+(r-l)/2;
if(nums[mid-1]<nums[mid] && nums[mid]<nums[mid+1])
l=mid;
else if(nums[mid-1]<nums[mid] && nums[mid]>nums[mid+1])
return(mid);
else
r=mid;
} if(nums[l]>nums[r])
return(l);
else
return(r);
}
}

33. Search in Rotated Sorted Array

三次二分...但加起来还是算logN嘛  【摊手

第一次:找数组中的最小值,记最小值的下标为idx

 将rotated array的数据值按xy坐标系画出来看一哈,大概是这样的:

                  '   |
' |
' |
'[fst] |
---------------------------------------------------------------
| '[lst]
| '
| '
| '
| '[最小] 可以发现,最小值左半边的数都是>=first的,最小值及其右半边的数都是<=lst的
按照OOOOXXXX的思路,通过二分缩小start~end的范围。注意循环里不需要判断mid是不是最小值点了(因为不好判断)
最后退出循环时,start~end的区间范围最多是2,且其中肯定包含最小值。手动min判断一下即可 def findmin(self, nums): #return index of min value
nl=len(nums)
fst=nums[0]
lst=nums[nl-1]
start=0
end=nl-1
while(start+1<end):
mid=(start+end)//2
if(nums[mid]>=fst):
start=mid
if(nums[mid]<=lst):
end=mid
return(start if nums[start]<nums[end] else end)

第二次:在有序数组nums[0..idx-1]中找target

第三次:在有序数组nums[idx..len-1]中找target

 class Solution:

     def findmin(self, nums):    #return index of min value
nl=len(nums)
fst=nums[0]
lst=nums[nl-1]
start=0
end=nl-1
while(start+1<end):
mid=(start+end)//2
if(nums[mid]>=fst):
start=mid
if(nums[mid]<=lst):
end=mid
return(start if nums[start]<nums[end] else end) def bs(self, nums, _start, _end, target):
start=_start
end=_end
while(start+1<end):
mid=(start+end)//2
if(nums[mid]==target):
return mid
if(nums[mid]<target):
start=mid
if(nums[mid]>target):
end=mid
if(nums[start]==target):
return start
if(nums[end]==target):
return end
return -1 def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if(len(nums)==0):
return -1
if(len(nums)==1):
return(0 if nums[0]==target else -1)
idx=self.findmin(nums)
#print(idx)
ans1=self.bs(nums,0,idx-1,target) if idx>0 else -1
#print(0,idx-1,ans1,nums)
ans2=self.bs(nums,idx,len(nums)-1,target) if idx<=len(nums)-1 else -1
#print(idx,len(nums)-1,ans2,nums)
return (ans1 if ans1!=-1 else ans2) sl=Solution()
print(sl.search([3,1], 1))
 class Solution {
public int binsearch(int x, int y, int[] nums, int target){
int start=x, end=y, mid=-1;
while(start+1<end){
mid=start+(end-start)/2;
if(nums[mid]==target)
return(mid);
if(nums[mid]<target)
start=mid;
if(nums[mid]>target)
end=mid;
}
if(nums[start]==target)
return(start);
else if(nums[end]==target)
return(end);
else
return(-1);
} public int search(int[] nums, int target) {
if(nums.length==0)
return(-1);
int start=0,end=nums.length-1,mid=-1;
int fst=nums[0], lst=nums[end];
while(start+1<end){
mid=start+(end-start)/2;
if(nums[mid]>fst)
start=mid;
if(nums[mid]<lst)
end=mid;
}
fst=start; lst=end;
//[0..fst] / [lst..length-1] int ans=binsearch(0, fst, nums, target);
if(ans!=-1)
return(ans);
return(binsearch(lst, nums.length-1, nums, target));
}
}

补充:快速幂

https://leetcode.com/problems/powx-n/

 class Solution:
def myPow(self, x, n):
"""
:type x: float
:type n: int
:rtype: float
"""
inc=x
ans=1
N=int(n)
flag=False
if(N==0):
return 1
if(N<0):
N=-N
flag=True
while(N>1):
if(N%2!=0):
ans=ans*inc
inc=inc*inc
N=N//2
#print(inc,ans,N)
ans=inc*ans
if(flag):
ans=1/ans
return ans sl=Solution()
xx=sl.myPow(2,-2)
print(xx)

类型4:二分答案

Copy Books

https://www.lintcode.com/problem/copy-books/description


三步翻转法

http://www.lintcode.com/problem/recover-rotated-sorted-array/

题意:对于类似4,5,1,2,3的数组,in place还原成1,2,3,4,5

sol:先找到5和1之间的这个位置(可以用二分法),然后按以下策略翻转数组:

1. 分别翻转两部分

45123

54321

2. 翻转整个数组

54321

12345

http://www.lintcode.com/problem/rotate-string/

abcde fg  ->  edcba gf

edcbagf  ->  fgabcde


二维矩阵找数问题

240. Search a 2D Matrix II

前面做过啦往上翻!    (‾◡◝)


辗转相除法

辗转相除法, 又名欧几里德算法, 是求最大公约数的一种方法。它的具体做法是:用较大的数除以较小的数,再用除数除以出现的余数(第一余数),再用第一余数除以出现的余数(第二余数),如此反复,直到最后余数是0为止。如果是求两个数的最大公约数,那么最后的除数就是这两个数的最大公约数。

 public int gcd(int big, int small) {
if (small != 0) {
return gcd(small, big % small);
} else {
return big;
}
}

http://www.lintcode.com/problem/greatest-common-divisor/


快速幂算法

递归版本:

 int power(int x, int n) {
if (n == 0) return 1;
if (n % 2 == 0) {
int tmp = power(x, n / 2);
return tmp * tmp;
} else {
int tmp = power(x, n / 2);
return tmp * tmp * x;
}
}

非递归版本:

 int power(int x, int n) {
int ans = 1, base = x;
while (n != 0) {
if (n % 2 == 1) {
ans *= base;
}
base *= base;
n = n / 2;
}
return ans;
}

非递归版本与递归版本原理相同,计算顺序略有不同。

因为递归是从大问题进入,划分子问题然后层层返回再求解大问题。这里要从小问题开始,直接求解大问题。
你可以打印出每次循环中 basebasebase 和 ansansans 的值,来理清楚其中的算法思路。

递归版本和非递归版本都应该熟练掌握,虽然递归版本更容易掌握和理解,且logN的计算深度也不会导致 Stack Overflow。但是面试官是很有可能为了加大难度让你在用非递归的版本写一遍的。

http://www.lintcode.com/problem/fast-power/
http://www.lintcode.com/problem/powx-n/


两个排序数组的中位数

在两个排序数组中,求他们合并到一起之后的中位数

时间复杂度要求:O(log(n+m)),其中 n, m 分别为两个数组的长度

http://www.lintcode.com/problem/median-of-two-sorted-arrays/

这个题有三种做法:

  1. 基于 FindKth 的算法。整体思想类似于 median of unsorted array 可以用 find kth from unsorted array 的解题思路。
  2. 基于中点比较的算法。一头一尾各自丢掉一些,去掉一半的时候,整个问题的形式不变。可以推广到 median of k sorted arrays.
  3. 基于二分的方法。二分 median 的值,然后再用二分法看一下两个数组里有多少个数小于这个二分出来的值

Leetcode Lect3 二分法总结的更多相关文章

  1. Leetcode之二分法专题-287. 寻找重复数(Find the Duplicate Number)

    Leetcode之二分法专题-287. 寻找重复数(Find the Duplicate Number) 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和  ...

  2. Leetcode之二分法专题-875. 爱吃香蕉的珂珂(Koko Eating Bananas)

    Leetcode之二分法专题-875. 爱吃香蕉的珂珂(Koko Eating Bananas) 珂珂喜欢吃香蕉.这里有 N 堆香蕉,第 i 堆中有 piles[i] 根香蕉.警卫已经离开了,将在 H ...

  3. Leetcode之二分法专题-704. 二分查找(Binary Search)

    Leetcode之二分法专题-704. 二分查找(Binary Search) 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 t ...

  4. Leetcode之二分法专题-744. 寻找比目标字母大的最小字母(Find Smallest Letter Greater Than Target)

    Leetcode之二分法专题-744. 寻找比目标字母大的最小字母(Find Smallest Letter Greater Than Target) 给定一个只包含小写字母的有序数组letters  ...

  5. Leetcode之二分法专题-1011. 在 D 天内送达包裹的能力(Capacity To Ship Packages Within D Days)

    Leetcode之二分法专题-1011. 在 D 天内送达包裹的能力(Capacity To Ship Packages Within D Days) 传送带上的包裹必须在 D 天内从一个港口运送到另 ...

  6. Leetcode之二分法专题-441. 排列硬币(Arranging Coins)

    Leetcode之二分法专题-441. 排列硬币(Arranging Coins) 你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币. 给定一个数字 n,找出可形 ...

  7. Leetcode之二分法专题-367. 有效的完全平方数(Valid Perfect Square)

    Leetcode之二分法专题-367. 有效的完全平方数(Valid Perfect Square) 给定一个正整数 num,编写一个函数,如果 num 是一个完全平方数,则返回 True,否则返回 ...

  8. Leetcode之二分法专题-374. 猜数字大小(374. Guess Number Higher or Lower)

    Leetcode之二分法专题-374. 猜数字大小(374. Guess Number Higher or Lower) 我们正在玩一个猜数字游戏. 游戏规则如下:我从 1 到 n 选择一个数字. 你 ...

  9. Leetcode之二分法专题-278. 第一个错误的版本(First Bad Version)

    Leetcode之二分法专题-278. 第一个错误的版本(First Bad Version) 你是产品经理,目前正在带领一个团队开发新的产品.不幸的是,你的产品的最新版本没有通过质量检测.由于每个版 ...

随机推荐

  1. tf.reshape

    tf.reshape(tensor, shape, name=None) 其中,tensor是向量,或者说矩阵 shape是转换后的向量,或者转换后的矩阵形状 [2,1]转换成二行一列 [2,-1]转 ...

  2. FMC228- 四路16位1.2Gsps DA FMC子卡模块

    FMC228- 四路16位1.2Gsps DA FMC子卡模块 一.概述          FMC连接器是一种高速多pin的互连器件,广泛应用于板卡对接的设备中,特别是在xilinx公司的所有开发板中 ...

  3. Object中有哪些公用方法?

    clone()方法 实现对象的浅复制,只有实现了Cloneable接口才能调用该方法. toString()方法 返回该对象的字符串表示. equals()方法: 在Object中与“==”的定义是一 ...

  4. console.log 不起作用

    devtool console.log 突然不起作用了

  5. File类常用方法和枚举

    新建一个file对象: File f = new File("F:\\01.JAVA基础300集\\05_常用类\\122.File类的使用.mp4"); (文件路径也可以用&qu ...

  6. jmeter性能工具 之监控cpu,内存等信息(四)

    1.jmeter 本身不支持直接监控 cpu,内存等信息,需要去官网下载控件 JMeterPlugins-Standard-1.4.0.zip    解压好将其中\lib\ext\JMeterPlug ...

  7. 如何在centos7中设置redis服务器开机自启动

    1.简单说明centos7系统中有不同类型的程序,一类是操作系统的服务程序,另一类是第三方程序,而redis就是第三方程序,每次关机后开机都要手工重新启动,很麻烦,那么如何把redis设置为开机自启动 ...

  8. Linux下git安装配置

    一.Linux下git安装配置 2013-07-28 20:32:10|  分类: 默认分类 |  标签:linux  git  server  |举报|字号 订阅     http://abomby ...

  9. Test 3.27 T1 立方体大作战

    Description ​ 一个叫做立方体大作战的游戏风靡整个 Byteotia.这个游戏的规则是相当复杂的,所以我们只介绍他的简单规则:给定玩家一个有 2n 个元素的栈,元素一个叠一个地放置.这些元 ...

  10. js把两个对象合并成一个对象

    Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象.它将返回目标对象 语法: Object.assign(target, ...sources)参数 targ ...