JAVA 二分

给定一个非负整数数组 nums 和一个整数 m ,你需要将这个数组分成 m 个非空的连续子数组。

设计一个算法使得这 m 个子数组各自和的最大值最小。

示例 1:

输入:nums = [7,2,5,10,8], m = 2
输出:18
解释:
一共有四种方法将 nums 分割为 2 个子数组。 其中最好的方式是将其分为 [7,2,5] 和 [10,8] 。
因为此时这两个子数组各自的和的最大值为18,在所有情况中最小。
示例 2:

输入:nums = [1,2,3,4,5], m = 2
输出:9
示例 3:

输入:nums = [1,4,4], m = 3
输出:4

class Solution {
    public int splitArray(int[] nums, int m) {
       int ri=0,le=0;
       for(int x:nums){
           ri +=x;
           if(le<x) le  =x ;
       }
       //ri 所有和 ,le 数组最大值
        while(le<=ri){
            int mid  =(ri+le)/2;
            if(check(nums,mid,m)) ri  =mid-1;//while 取=,ri,le都要改变
            else le = mid+1;
        }
        return le;
    }
    boolean check(int nums[],int ret,int cntt){
             int sum=0,cnt=1;
             for(int x:nums){
                 if(sum+x>ret) {//需要再分一组
                     cnt++;
                     sum=x;
                 }
                 else{
                     sum+=x;
                 }
             }
             return cnt<=cntt;//需要组数<=要求,说明ret可以继续小,因为组数增加,最大值减小
    }
}

33. 搜索旋转排序数组

难度中等

整数数组 nums 按升序排列,数组中的值 互不相同 。

在传递给函数之前,nums 在预先未知的某个下标 k0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。

给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。

时间复杂度  logn

//一定有一侧是有序的
class Solution {
    public int search(int[] nums, int target) {
               int n =nums.length;
               if(n==1)  return nums[0]==target?0:-1;
               int l=0,r=n-1;
               while(l<=r){
                   int mid=(l+r)/2;
                   if(nums[mid]==target)  return mid;
                   if(nums[mid]>=nums[0]){//[l,mid]有序
                            if(target>=nums[0]&&target<nums[mid]){
                                r = mid-1;
                            }
                            else{
                                l=mid+1;
                            }
                   }
                   else{  //[mid+1,r]有序
                               if(target>nums[mid]&&target<=nums[r])  {
                                   l=mid+1;
                               }
                               else{
                                   r  =mid-1;
                               }
                   }
               }
               return -1;
    }
}
原文地址:https://www.cnblogs.com/tingtin/p/15791953.html