leetcode刷题记录2021年4月26日

周六周日做了没写,今天就一并写上,一共三道题

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;
    }
};

我代码有点冗长,而且有能优化的地方。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值