Leetcode Lect3 二分法总结
二分法模板
非递归版本:
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: 为了避免死循环。二分法的模板中,整个程序架构分为两个部分:
- 通过 while 循环,将区间范围从 n 缩小到 2 (只有 start 和 end 两个点)。
- 在 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/
这个题有三种做法:
- 基于 FindKth 的算法。整体思想类似于 median of unsorted array 可以用 find kth from unsorted array 的解题思路。
- 基于中点比较的算法。一头一尾各自丢掉一些,去掉一半的时候,整个问题的形式不变。可以推广到 median of k sorted arrays.
- 基于二分的方法。二分 median 的值,然后再用二分法看一下两个数组里有多少个数小于这个二分出来的值
Leetcode Lect3 二分法总结的更多相关文章
- Leetcode之二分法专题-287. 寻找重复数(Find the Duplicate Number)
Leetcode之二分法专题-287. 寻找重复数(Find the Duplicate Number) 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 ...
- Leetcode之二分法专题-875. 爱吃香蕉的珂珂(Koko Eating Bananas)
Leetcode之二分法专题-875. 爱吃香蕉的珂珂(Koko Eating Bananas) 珂珂喜欢吃香蕉.这里有 N 堆香蕉,第 i 堆中有 piles[i] 根香蕉.警卫已经离开了,将在 H ...
- Leetcode之二分法专题-704. 二分查找(Binary Search)
Leetcode之二分法专题-704. 二分查找(Binary Search) 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 t ...
- Leetcode之二分法专题-744. 寻找比目标字母大的最小字母(Find Smallest Letter Greater Than Target)
Leetcode之二分法专题-744. 寻找比目标字母大的最小字母(Find Smallest Letter Greater Than Target) 给定一个只包含小写字母的有序数组letters ...
- Leetcode之二分法专题-1011. 在 D 天内送达包裹的能力(Capacity To Ship Packages Within D Days)
Leetcode之二分法专题-1011. 在 D 天内送达包裹的能力(Capacity To Ship Packages Within D Days) 传送带上的包裹必须在 D 天内从一个港口运送到另 ...
- Leetcode之二分法专题-441. 排列硬币(Arranging Coins)
Leetcode之二分法专题-441. 排列硬币(Arranging Coins) 你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币. 给定一个数字 n,找出可形 ...
- Leetcode之二分法专题-367. 有效的完全平方数(Valid Perfect Square)
Leetcode之二分法专题-367. 有效的完全平方数(Valid Perfect Square) 给定一个正整数 num,编写一个函数,如果 num 是一个完全平方数,则返回 True,否则返回 ...
- Leetcode之二分法专题-374. 猜数字大小(374. Guess Number Higher or Lower)
Leetcode之二分法专题-374. 猜数字大小(374. Guess Number Higher or Lower) 我们正在玩一个猜数字游戏. 游戏规则如下:我从 1 到 n 选择一个数字. 你 ...
- Leetcode之二分法专题-278. 第一个错误的版本(First Bad Version)
Leetcode之二分法专题-278. 第一个错误的版本(First Bad Version) 你是产品经理,目前正在带领一个团队开发新的产品.不幸的是,你的产品的最新版本没有通过质量检测.由于每个版 ...
随机推荐
- 在centOS7.2上编译gcc4.4.7
1.前置 首先,可以参考我的上篇文章,在centOS7.2上编译gcc4.1.2,过程基本一致,这里只对可能遇到的错误情况进行说明. 2.安装texinfo4.8 我的centos7.2版本,自带的是 ...
- linux--基础知识4
#当前已什么用户登陆,创建的目录或文件,他的属组和主就是谁 #用户对目录拥有的几种权限 # ll -d查看目录当前权限信息 #r:可以查看该目录下的子文件名,子目录 #w:可以在该目录下创建,删除,重 ...
- Sass @warn
@warn 和 @debug 功能类似,用来帮助我们更好的调试 Sass.如: @mixin adjust-location($x, $y) { @if unitless($x) { @warn &q ...
- Centos7 tomcat 启动权限
Cannot find bin/catalina.sh The file is absent or does not have execute permission This file is ne ...
- [python 学习] logging模块
1.将简单日志打印到屏幕: import logging logging.debug('debug message') logging.info('info message') logging.war ...
- jquery 模态对话框传值,删除,新增表格行
个人的练习代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- bzoj4002 [JLOI2015]有意义的字符串 特征根+矩阵快速幂
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4002 题解 神仙题. 根据下面的一个提示: \[ b^2 \leq d \leq (b+1)^ ...
- HY 的惩罚 (Trie 树,博弈论)
[问题描述] hy 抄题解又被老师抓住了,现在老师把他叫到了办公室. 老师要 hy 和他玩一个游 戏.如果 hy 输了,老师就要把他开除信息组; 游戏分为 k 轮.在游戏开始之前,老师会将 n 个由英 ...
- laravel的使用
1.先下载composer.phar 下载地址:https://getcomposer.org/download/ 把composer.phar拷贝到自己的项目目录中,执行以下代码: php comp ...
- app中使用
KeepLive.startWork(this, KeepLive.RunMode.ROGUE, ForegroundNotification("Title", "mes ...