算法实战:牛客23458题数组分割最小化最大和的二分查找与贪心解法
一、问题背景与理解
牛客23458题要求将一个数组分割成m个子数组,使得这些子数组各自和的最大值最小。这是一个典型的算法优化问题,结合了二分查找和贪心算法的思想。
二、完整代码实现(带详细注释)
#include <iostream> #include <vector> #include <algorithm> #include <numeric> using namespACe std; bool canSplit(const vector<int>& nums, int m, long long maxSum) { int count = 1; long long currentSum = 0; for (int num : nums) { if (currentSum + num > maxSum) { currentSum = num; count++; if (count > m) return false; } else { currentSum += num; } } return true; } int minMaxPartition(vector<int>& nums, int m) { long long left = *max_element(nums.begin(), nums.end()); long long right = accumulate(nums.begin(), nums.end(), 0LL); while (left < right) { long long mid = left + (right - left) / 2; if (canSplit(nums, m, mid)) { right = mid; } else { left = mid + 1; } } return left; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; vector<int> nums(n); for (int i = 0; i < n; ++i) { cin >> nums[i]; } cout << minMaxPartition(nums, m) << endl; return 0; }
三、算法核心思想
二分查找:在可能的最小最大和范围内进行搜索
贪心验证:检查给定最大和限制下是否可行
边界确定:下界为数组最大值,上界为数组总和
最优分割:找到满足条件的最小最大和
四、复杂度分析
时间复杂度:O(n log S),其中S为数组总和
空间复杂度:O(1),仅使用常数空间
五、关键技巧
二分查找的应用场景识别
贪心算法的验证函数设计
边界条件的合理确定
数值溢出的预防处理
原创内容 转载请注明出处