二分查找

二分查找(上)
供自己记录用,如果错误 欢迎指正 小姐姐在此谢过
题目1283
这道题尝试了暴力解法,很明显会超时
首先给数组排个顺序,左界限为1,右边为最大的数,取中间数进行除法运算结果取上整,比较大小来决定下一次在哪个区间内进行判断。二分查找最容易出错的就是是否取等号的问题。

package bianry_search;import java.lang.reflect.Array;
import java.util.Arrays;

import javax.swing.text.StyleContext.SmallAttributeSet;

public class Solutio1283 {
	public static void main(String[] args){
		int[] nums = new int[]{2,3,5,7,11};
		int threshold = 11;
		int ans = new Solutio1283().smallestDivisor(nums, threshold);
		System.out.print(ans);
		
	}
//不采用二分查找的以下方法过于耗时
//	public int SmallestDivisor(int[] nums,int threshold){
//		int a = 1,b = threshold;
//		int flag = 0;
//		while(flag>b|flag==0){
//			flag=0;
//			for(int num:nums){
//				double c = (double)num/(double)a;
//				flag += Math.ceil(c);
				System.out.print(c+" "+Math.ceil(c)+" ");
//			}
//			a++;
			System.out.println(flag+" "+a);
//		}
//		return a-1;
//	}
	public static int smallestDivisor(int[] nums,int thresold){
		if(nums.length<0){
			return -1;
		}
		Arrays.sort(nums);
		int left = 1,right = nums[nums.length-1];
		while(left<right){
			int mid=(left+right)/2;
			int sum = 0;
			for(int num:nums){
				double a = (double)num/(double)mid;
				sum += Math.ceil(a);//这里在进行处之前就需要进行强制转换了,不如可以直接判断好了
//    			if(mid != 0){
//    				if(num % mid == 0){
//    					sum += num / mid;
//    				}else{
//    					sum += num / mid + 1;
//    				}
//    			}
//				System.out.print(a+" "+sum+" "+left+"-"+right+""+"\n");
			}
			if(sum < thresold)
				right = mid;
			else
				left = mid+1;
		}
		return left;
	}
	

}

在这里插入图片描述

50.求pow(x,n) 分治思想

class Solution {
    public double myPow(double x,int n){
		if(n ==0|x==1.0)
			return 1.0;
		if(x == 0.0)
			return 0.0;
		if(n < 0){
			x = 1 / x;
			n = -n;
		}
		double res = 1.0;
		while(n !=0 ){
			if((n & 1)==1){
				res *= x;
			}
			x *=x;
			n >>>= 1;
		}
		return res;
	}
}

第五十题leetcode300

class Solution {
	public int lengthOfLIS(int[] nums){
		int len = nums.length;
		if(len <= 0)
			return 0;
		if(len == 1)
			return 1;
		int[] tail = new int[len];
		tail[0] = nums[0];
		int end = 0;
		for(int i = 1;i < len;i ++){
			if(tail[end] < nums[i])
				tail[++end] = nums[i];
			else{
				int left = 0;
				int right = end;
				while(left < right){
					int mid = left + (right - left)/2;
					if(tail[mid] < nums[i])
						left = mid + 1;
					else
						right = mid;
				}
				tail[left] = nums[i];
			}
				
		}
		return ++end;
	}
}

这个理解了tail数组的含义就变得容易了.这个题可以有很多变形
马戏团人塔
俄罗斯套娃信封
对二维数组进行一个处理就可,然后求宽(体重)的最长上升子序列

Arrays.sort(envelopes,new Comparator<int[]>() {
			public int compare(int[] a, int[] b){
				return a[0]==b[0]?b[1]-a[1]:a[0]-b[0];
			}
		});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值