有一点点难受这个算法,俩个题目给我的感觉代码都差不多但是意思大相径庭,我暂时没有很好的解释,先把他放在这里,看看我之后能不能很好的解释:
第一题
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
进阶:你可以设计并实现时间复杂度为 $O(\log n)$ 的算法解决此问题吗?
示例 1:
- 输入:nums = [5,7,7,8,8,10], target = 8
- 输出:[3,4]
示例 2:
- 输入:nums = [5,7,7,8,8,10], target = 6
- 输出:[-1,-1]
示例 3:
- 输入:nums = [], target = 0
- 输出:[-1,-1]
代码:
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int left=Left(nums,target);
int right=Right(nums,target);
if(left==-2||right==-2){
return {-1,-1};
}
if (right-left>1){
return {left + 1, right - 1};
}
return {-1, -1};
}
private:
int Left(vector<int>& nums, int target){
int left=0;
int right=nums.size()-1;
int flag=-2;
while(left<=right){
int middle=left+(right-left)/2;
if(nums[middle]>=target){
right=middle-1;
flag=right;
}else{
left=middle+1;
}
}
return flag;
}
int Right(vector<int>& nums, int target){
int left=0;
int right=nums.size()-1;
int flag=-2;
while(left<=right){
int middle=left+(right-left)/2;
if(nums[middle]>target){
right=middle-1;
}else{
left=middle+1;
flag=left;
}
}
return flag;
}
};
第二题
题目描述
木材厂有 n 根原木,现在想把这些木头切割成 k 段长度均为 l 的小段木头(木头有可能有剩余)。
当然,我们希望得到的小段木头越长越好,请求出 l 的最大值。
木头长度的单位是 cm,原木的长度都是正整数,我们要求切割得到的小段木头的长度也是正整数。
例如有两根原木长度分别为 11 和 21,要求切割成等长的 6 段,很明显能切割出来的小段木头长度最长为 5。
输入格式
第一行是两个正整数 n,k,分别表示原木的数量,需要得到的小段的数量。
接下来 n 行,每行一个正整数 Li,表示一根原木的长度。
输出格式
仅一行,即 l 的最大值。
代码:
#include <iostream>
#include <cstring>
using namespace std;
int check(int middle,int weight[],int n);
int main(){
int n,k;
cin>>n>>k;
int weight[n];
int sum=0;
int max1=0;
for(int i=0;i<n;i++){
cin>>weight[i];
sum+=weight[i];
max1=max(max1,weight[i]);
}
int left=1;
int right=max1;
while(left<=right){
int middle=left+(right-left)/2;
if(check(middle,weight,n)>=k){
left=middle+1;
}else{
right=middle-1;
}
}
if(sum<k){
cout<<0;
}else{
cout<<right;
}
return 0;
}
int check(int middle,int weight[],int n){
int sum = 0;
for(int i = 0;i < n;i++) {
sum+=weight[i]/middle;
}
return sum;
}