周六周日做了没写,今天就一并写上,一共三道题
897. 递增顺序搜索树
没什么好说的,基础题,中序遍历读一遍再插进去就行了。
class Solution {
vector<int> value;
public:
TreeNode* increasingBST(TreeNode* root) {
TreeNode* new_root = nullptr;
tfs(root);
//for(int i=0;i<value.size();i++)
//cout<<value[i]<<' ';
cout<<endl;
for(int i=0;i<value.size();i++)
insert(new_root,value[i]);
return new_root;
}
void tfs(TreeNode* root)
{
if(root == nullptr)
return;
tfs(root->left);
value.push_back(root->val);
tfs(root->right);
}
void insert(TreeNode* &root,int val)
{
if(root == nullptr)
{
root = new TreeNode(val);
return;
}
if(root->val > val)
{
if(root->left == nullptr)
{
TreeNode* newnode = new TreeNode(val);
root->left = newnode;
return;
}
insert(root->left,val);
}else{
if(root->right == nullptr)
{
TreeNode* newnode = new TreeNode(val);
root->right = newnode;
return;
}
insert(root->right,val);
}
}
};
377. 组合总和 Ⅳ
动态规划,转移方程为:
dp[i] = sum(dp[k-num[i-1]])(0<=k<i)
需要注意的是,会存在超出表示范围的数,忽略掉就行
class Solution {
int res = 0;
int target;
public:
int combinationSum4(vector<int>& nums, int target) {
long long dp[target+1];
dp[0]=1;
for(int i=1;i<target+1;i++)
{
dp[i]=0;
for(int num : nums)
{
if(i>=num && dp[i-num]<INT_MAX)
dp[i]+=dp[i-num];
}
}
return dp[target];
}
/*
void dfs(vector<int>& nums,int tmp)
{
if(tmp == target)
{
res++;
}
if(tmp > target)
{
return ;
}
for(int i=0;i<nums.size();i++)
{
dfs(nums,tmp+nums[i]);
}
}*/
};
1011. 在 D 天内送达包裹的能力
前缀和加二分搜索
根据题意,很容易确定一个上限和一个下限。
我设置的下限为sum(nums)/D,上限为sum(nums),在模糊点也没关系,只要保证不超时就行。
利用前缀和,可以再O(n)的规模上求出一个容量是不是可行,接下来二分搜索就行了。
class Solution {
public:
int shipWithinDays(vector<int>& weights, int D) {
vector<int> pre_sum(weights.size()+1);
pre_sum[0]=0;
for(int i=1;i<weights.size()+1;i++)
pre_sum[i]=pre_sum[i-1]+weights[i-1];
int max = pre_sum[pre_sum.size()-1];
int min = max/D;
//cout<<max<<' '<<min<<endl;
int res = -1;
while(min <= max)
{
//cout<<max<<' '<<min<<endl;
int mid = (max+min)/2;
//int mid_sub_1 = mid - 1;
bool mid_p = istrue(pre_sum,D,mid);
/*bool mid_sub_1_p = istrue(pre_sum,D,mid_sub_1);
if(mid_p == true && mid_sub_1_p == false)
{
res = mid;
break;
}*/
if(mid_p == true)
res = mid;
if(mid_p == false)
min = mid + 1;
else
max = mid - 1;
}
//istrue(pre_sum,D,2);
return res;
}
bool istrue(vector<int>& pre_sum, int D,int cap)
{
//cout<<"aaaaa"<<cap<<endl;
int tmpD = 0,mark = 0;
for(int i=1;i<pre_sum.size();i++)
{
if(pre_sum[i] - pre_sum[i-1] > cap)
return false;
if(mark >= 0 && pre_sum[i] - pre_sum[mark] > cap)
{
mark = i - 1;
tmpD++;
}else if(mark >= 0 && pre_sum[i] - pre_sum[mark] == cap){
mark = i;
tmpD++;
}
}
//cout<<endl;
if(pre_sum[pre_sum.size()-1]-pre_sum[mark]!=0)
tmpD++;
//cout<<mark<<' '<<tmpD<<endl;
if(tmpD <= D)
return true;
return false;
}
};
我代码有点冗长,而且有能优化的地方。