二分查找
-
- 检查一个数是否在数组中占绝大多数
- 不动点
- 猜数字大小
- 第 k 个缺失的正整数
- 找出数组排序后的目标下标
- 早餐组合
- 第一个错误的版本
- 采购方案
- 和为s的两个数字
- 排序数组中两个数字之和
- 查找插入位置
- 山峰数组的顶部
- 求平方根
- 最接近的二叉搜索树值
检查一个数是否在数组中占绝大多数
class Solution {
public int leftest(int[] nums,int target){
int left=0,right=nums.length-1;
int mid=0;
while(left<right){
mid=left+((right-left)>>1);
if(nums[mid]>=target){
right=mid;
}
else{
left=mid+1;
}
}
return left;
}
public int rightest(int[] nums,int target){
int left=0,right=nums.length-1;
int mid=0;
while(left<right){
mid=left+((right-left)>>1);
if(nums[mid]>target){
right=mid;
}
else{
left=mid+1;
}
}
return left;
}
public boolean isMajorityElement(int[] nums, int target) {
int left=leftest(nums,target);
int right=rightest(nums,target);
if(left==right){
return false;
}
return right-left+1>nums.length/2;
}
}
不动点
class Solution {
public int fixedPoint(int[] arr) {
int left=0,right=arr.length-1;
int mid=0;
while(left<right){
mid=left+((right-left)>>1);
if(arr[mid]==mid){
right=mid;
}else if(arr[mid]<mid){
left=mid+1;
}else{
right=mid-1;
}
}
return left==arr[left]?left:-1;
}
}
猜数字大小
public class Solution extends GuessGame {
public int guessNumber(int n) {
int left=1,right=n;
int mid=0;
while(left<=right){
mid=left+((right-left)>>1);
if(guess(mid)==0)return mid;
else if(guess(mid)>0){
left=mid+1;
}else{
right=mid-1;
}
}
return left;
}
}
第 k 个缺失的正整数
class Solution {
public int findKthPositive(int[] arr, int k) {
int left=0,right=arr.length-1;
if(arr[arr.length-1]==arr.length)return arr[arr.length-1]+k;
if(arr[0]-1>=k){
return k;
}else{
k-=(arr[0]-1);
}
int mid=0;
while(left<right){
mid=left+((right-left)>>1);
if(left==mid)break;
else if(arr[mid]-arr[left]-(mid-left)>0){
if(arr[mid]-arr[left]-(mid-left)<k){
k-=arr[mid]-arr[left]-(mid-left);
left=mid;
}else{
right=mid;
}
}else{
left=mid;
}
}
if(left<arr.length-1){
if(arr[left]+1==arr[left+1]){
return arr[arr.length-1]+k;
}else{
return arr[left+1]-arr[left]-1>=k?arr[left]+k:arr[left+1]+(k-(arr[left+1]-arr[left]-1));
}
}
return arr[left]+k;
}
}
找出数组排序后的目标下标
class Solution {
public int leftest(int[] nums,int target){
int left=0,right=nums.length-1;
int mid=0;
while(left<right){
mid=left+((right-left)>>1);
if(nums[mid]<target){
left=mid+1;
}else{
right=mid-1;
}
}
return left;
}
public int rightest(int[] nums,int target){
int left=0,right=nums.length-1;
int mid=0;
while(left<right){
mid=left+((right-left)>>1);
if(nums[mid]<=target){
left=mid+1;
}else{
right=mid-1;
}
}
return left;
}
public List<Integer> targetIndices(int[] nums, int target) {
Arrays.sort(nums);
int left=leftest(nums,target);
int right=rightest(nums,target);
List<Integer>list=new ArrayList<>();
for(int i=left;i<=right;++i){
if(nums[i]==target){
list.add(i);
}
}
return list;
}
}
早餐组合
class Solution {
public int breakfastNumber(int[] staple, int[] drinks, int x) {
Arrays.sort(staple);
Arrays.sort(drinks);
int ans=0;
int index=0;
for(int s=0;s<staple.length;++s){
if(staple[s]>=x)break;
int rest=x-staple[s];
index=getIndex(drinks,rest);
if(rest<drinks[index]){
ans+=index;
}else{
ans+=index+1;
}
ans%=1000000007;
}
return ans%1000000007;
}
public int getIndex(int[] drinks,int x){
int left=0,right=drinks.length-1;
int mid=0;
while(left<right){
mid=left+((right-left)>>1);
if(drinks[mid]>x){
right=mid-1;
}else{
left=mid+1;
}
}
return left;
}
}
第一个错误的版本
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int left=1,right=n;
int mid=0;
while(left<=right){
mid=left+((right-left)>>1);
if(isBadVersion(mid)){
right=mid-1;
}else{
left=mid+1;
}
}
return left;
}
}
采购方案
class Solution {
public int fun(int[] nums,int target){
Arrays.sort(nums);
int ans=0;
for(int i=0;i<nums.length-1;++i){
if(nums[i]>=target)break;
int index=getIndex(nums,target-nums[i],i+1,nums.length-1);
if(target-nums[i]>=nums[index]){
ans+=(index-i);
}else{
ans+=(index-i-1);
}
ans%=1000000007;
}
return ans%1000000007;
}
public int getIndex(int[] nums,int x,int left,int right){
if(left==right)return left;
int mid=0;
while(left<right){
mid=left+((right-left)>>1);
if(nums[mid]>x){
right=mid-1;
}else{
left=mid+1;
}
}
return left;
}
public int purchasePlans(int[] nums, int target) {
return fun(nums,target);
}
}
和为s的两个数字
class Solution {
public int index(int[] nums,int x,int left,int right){
int mid=0;
while(left<right){
mid=left+((right-left)>>1);
if(nums[mid]==x)return mid;
else if(nums[mid]<x){
left=mid+1;
}else{
right=mid-1;
}
}
return left;
}
public int[] twoSum(int[] nums, int target) {
int[] ans=new int[2];
for(int i=0;i<nums.length-1;++i){
int cur=index(nums,target-nums[i],i+1,nums.length-1);
if(target-nums[i]==nums[cur]){
ans[0]=nums[i];
ans[1]=target-nums[i];
break;
}
}
return ans;
}
}
排序数组中两个数字之和
class Solution {
public int index(int[] numbers,int x,int left,int right){
int mid=0;
while(left<right){
mid=left+((right-left)>>1);
if(numbers[mid]==x)return mid;
else if(numbers[mid]<x){
left=mid+1;
}else{
right=mid-1;
}
}
return left;
}
public int[] twoSum(int[] numbers, int target) {
int[] ans=new int[2];
int cur=0;
for(int i=0;i<numbers.length-1;++i){
cur=index(numbers,target-numbers[i],i+1,numbers.length-1);
if(numbers[cur]==target-numbers[i]){
ans[0]=i;
ans[1]=cur;
break;
}
}
return ans;
}
}
查找插入位置
class Solution {
public int searchInsert(int[] nums, int target) {
int left=0,right=nums.length-1;
int mid=0;
while(left<=right){
mid=left+((right-left)>>1);
if(nums[mid]==target)return mid;
else if(nums[mid]<target){
left=mid+1;
}else{
right=mid-1;
}
}
return left;
}
}
山峰数组的顶部
class Solution {
public int process1(int[] arr){
for(int i=0;i<arr.length-1;++i){
if(arr[i]>arr[i+1]){
return i;
}
}
return 0;
}
public int process2(int[] arr){
int left=0,right=arr.length-1;
int mid=0;
while(left<=right){
mid=left+((right-left)>>1);
if(mid==0){
left=mid+1;
}
else if(mid==arr.length-1){
right=mid-1;
}
else if(arr[mid]>arr[mid-1]&&arr[mid]>arr[mid+1]){
return mid;
}else if(arr[mid]>arr[mid-1]&&arr[mid]<arr[mid+1]){
left=mid+1;
}else{
right=mid-1;
}
}
return 0;
}
public int peakIndexInMountainArray(int[] arr) {
return process2(arr);
}
}
求平方根
class Solution {
public int mySqrt(int x) {
if(x==0||x==1)return x;
long left=1,right=x/2;
long mid=left+((right-left)>>1);
while(left<=right){
mid=left+((right-left)>>1);
if(mid*mid==x){
break;
}
else if(mid*mid<x){
if((mid+1)*(mid+1)>x)break;
left=mid+1;
}
else{
right=mid-1;
}
}
return (int)mid;
}
}
最接近的二叉搜索树值
class Solution {
public int closestValue(TreeNode root, double target) {
TreeNode cur=root;
int ans=0;
double min=Integer.MAX_VALUE;
while(cur!=null){
if(min>=Math.abs(cur.val-target)){
min=Math.abs(cur.val-target);
ans=cur.val;
}
if(target<cur.val){
cur=cur.left;
}else{
cur=cur.right;
}
}
return ans;
}
}