二分_元素不在数组中的情况左右返回值.cpp
https:
二分_展厅人数.cpp
while (leftLimit < rightLimt) {
uint32_t midLimit = leftLimit + (rightLimt - leftLimit) / 2;
if (isFinsh(nums, midLimit, cnt)) {
leftLimit = midLimit;
} else {
rightLimt = midLimit - 1;
}
}
return leftLimit;
while (left < right) {
int midSpeed = left + (right - left) / 2;
if (isFinsh(piles, midSpeed, H)) {
right = midSpeed;
} else {
left = midSpeed + 1;
}
}
return right;
class Solution {
public:
int isFinsh(const vector<int> &nums, int midLimit, int cnt)
{
int numSunm = 0;
for (auto num : nums) {
if (num >= midLimit) {
numSunm += midLimit;
} else {
numSunm += num;
}
}
return numSunm <= cnt ? true : false;
}
int ManageTourists(const vector<int> &nums, int cnt)
{
uint32_t numsSum = 0;
for (auto num : nums) {
numsSum += num;
}
if (numsSum <= cnt) {
return -1;
}
uint32_t leftLimit = 0;
uint32_t rightLimt = numsSum;
while (leftLimit < rightLimt) {
uint32_t midLimit = leftLimit + (rightLimt - leftLimit) / 2;
if (isFinsh(nums, midLimit, cnt)) {
leftLimit = midLimit;
} else {
rightLimt = midLimit - 1;
}
}
return leftLimit;
}
};
int main()
{
vector<int> input { 1, 4, 2, 5, 5, 1, 6 };
int cnt = 13;
Solution *s = new Solution();
int res = s->ManageTourists(input, cnt);
cout << res << endl;
system("pause");
return 0;
}
二分_找目标值左右边界索引(带模板).cpp
class Solution {
public:
int leftBound(vector<int>& nums, int target) {
int left = 0;
int right = nums.size();
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] > target) {
right = mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] == target) {
right = mid;
}
}
return right;
}
int rightBound(vector<int>& nums, int target) {
int left = 0;
int right = nums.size();
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] > target) {
right = mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] == target) {
left = mid + 1;
}
}
return left - 1;
}
vector<int> searchRange(vector<int>& nums, int target) {
int left = leftBound(nums, target);
int right = rightBound(nums, target);
vector<int> res(2, 0);
if (left <= right && nums[left] == target && nums[right] == target) {
res[0] = left;
res[1] = right;
} else {
res[0] = -1;
res[1] = -1;
}
return res;
}
};
int main()
{
vector<int> nums = { 5,7,7,8,8,10 };
Solution *s = new Solution();
vector<int> res = s->searchRange(nums, 8);
system("pause");
return 0;
}
二分法反向操作.cpp
某雪场共有 N 座雪山,数组 altitude中存储了各雪山海拔(精确到整数)。雪场出售新手票与老手票,新手区票价较高。
若该雪场内最高海拔与最低海拔的差值大于 difference,则为老手区;否则为新手区。现在是滑雪活动旺季,雪场经营者希望获得更大收益,想要将整个雪场打造成新手雪场。
改造某座雪山海拔高度的成本为:变更高度的平方。注意: 变更高度仅可为整数; 变更工程可增加雪山海拔,也可降低雪山海拔; 请问雪场经营者改造需要投入的最少成本是多少(即:所有改造雪山的成本之和)?
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
示例 1: 输入:altitude = [5,1,4,3,8], difference = 3 输出:8
解释:将 1 变成 3,8 变成 6 ,这时最高是 6,最小是 3,相差不超过 3。需要成本为:2^2 + 2^2 = 8
示例 2: 输入:altitude = [1,2,99999,3,100000], difference = 3 输出:998679962
解释:将 1,2 和 3 分别变为 40000,将 99999 和 100000 分别变为 40003,此时最高为 40003,最低为 40000,相差不超过 3,此时需要成本为 11998680039,为最小值,取模后为 998679962 提示: 1 <= altitude.length <= 10^5 1 <= altitude[i],difference <= 10^5
思路:取平均数,从下界到上界依次计算总值,取最小。
此题主要注意点在大数表示,用int内部平方相减/相乘很容易整数溢出。
class Solution {
public:
int minPayment(const vector<int> &altitude, int difference) {
long sum = accumulate(altitude.begin(), altitude.end(), 0);
int mean = (int) (sum / altitude.size());
long long res = INT_MAX;
long long mod = 1e9 + 7;
for (int h = mean - difference; h <= mean + difference; h++) {
long long floor = h;
long long cell = h + difference;
long long 0;
for (auto a : altitude) {
if (a >= floor && a <= cell) {
continue;
} else if (a > cell) {
long long dis = (((long long)a - cell) * ((long long)a - cell));
oneCost += dis;
} else if (a < floor){
long long dis = (((long long)a - floor) * ((long long)a - floor));
oneCost += dis;
}
}
oneCost %= mod;
res = std::min(res, oneCost);
}
return (int) res;
}
};