410.分割数组的最大值
给定一个非负整数数组 nums
和一个整数 m
,你需要将这个数组分成 m
个非空的连续子数组。
设计一个算法使得这 m
个子数组各自和的最大值最小。
力扣解法一:动态规划
class Solution {
public:
int splitArray(vector<int>& nums, int m) {
int n = nums.size();
vector<vector<long long>>f(n + 1, vector<long long>(m + 1, LLONG_MAX));
vector<long long>sub(n + 1, 0);
for(int i = 0; i < n; i++){
sub[i + 1] = sub[i] + nums[i];
}
f[0][0] = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= min(i, m); j++){
for(int k = 0; k < i; k++){
f[i][j] = min(f[i][j], max(f[k][j - 1], sub[i] - sub[k]));
}
}
}
return (int)f[n][m];
}
};
力扣解法二:二分查找+贪心
class Solution {
public:
bool check(vector<int>& nums, int x, int m){
long long sum = 0;
int cnt = 1;
for(int i = 0; i < nums.size(); i++){
if(sum + nums[i] > x){
cnt++;
sum = nums[i];
}else{
sum += nums[i];
}
}
return cnt <= m;
}
int splitArray(vector<int>& nums, int m) {
long long left = 0, right = 0;
for(int i = 0; i < nums.size(); i++){
right += nums[i];
if(left < nums[i]){
left = nums[i];
}
}
while(left < right){
long long mid = left + (right - left) / 2;
if(check(nums, mid, m)){
right = mid;
}else{
left = mid + 1;
}
}
return left;
}
};
收获总结:
1.要回顾一下动态规划的用法,总结一下所有算法,不要做一个专题只想一种方法。
2.二分查找的方式很妙,不再是以坐标为基准,而是以最大元素到和取mid验证。
3.做题时可以考虑封装函数结合使用。
483.最小好进制
以字符串的形式给出 n
, 以字符串的形式返回 n
的最小 好进制 。
如果 n
的 k(k>=2)
进制数的所有数位全为1,则称 k(k>=2)
是 n
的一个 好进制 。
力扣解法:
class Solution {
public:
string smallestGoodBase(string n) {
long nVal = stol(n);
int mMax = floor(log(nVal) / log(2));
for (int m = mMax; m > 1; m--) {
int k = pow(nVal, 1.0 / m);
long mul = 1, sum = 1;
for (int i = 0; i < m; i++) {
mul *= k;
sum += mul;
}
if (sum == nVal) {
return to_string(k);
}
}
return to_string(nVal - 1);
}
};
class Solution {
public:
long long check( long long num, int len ) {
long long res = 0;
for( int i = 0; i < len; ++i ) {
res = res * num + num;
}
return res;
}
string smallestGoodBase(string n) {
long long num = stoll( n );
num--;
string ans = "";
long long t = num;
for( int i = 1; i <= 60; ++i ) {
if( i > 1 ) t = pow( num, 1.0 / i );
if( t > 1 && check(t, i) == num ) {
ans = to_string(t);
}
}
return ans;
}
};
收获总结:
1.注意这种解法,二分查找验证这个数行不行 n×logn。