2022.4.16日记

前情回顾:断了好多天的日记又开始复写,因为从4月13到4月16号晚上,都在疲于装系统的事情,搞得焦头烂额,但确实也收获了很多,学会了uefi引导与mbr引导,单硬盘与多硬盘的区别,下面的装机网址真的好,要常读常新。

https://www.cnblogs.com/masbay/articles/10745170.html?utm_source=wechat_session&utm_medium=social&utm_oi=843948068373143552

其中由于实验室电脑(实验室台式机电脑没有无线网卡)有线连接的问题,不知道是其ip地址不够的问题还是什么,其一直会出现网络断断续续的情况,不过好在解决了这个问题,是通过硬件解决的,重新加一个路由器,然后从路由器里连出网线插入到电脑上,有线连接就不会断。

今日正常:

  1. 回顾背包问题,在面对0-1背包的时候,状态满足条件下能转移的是否需要转移,这个是需要比较的,而不是直接让其转移,看最终谁更能符合我们的最终条件
		// 装入或者不装入背包,择优
		dp[i][w] = Math.max(
		    dp[i - 1][w - wt[i-1]] + val[i-1], 
		    dp[i - 1][w]
  1. 背包问题引出的组合数与排列数问题

https://leetcode-cn.com/problems/coin-change-2/solution/ling-qian-dui-huan-iihe-pa-lou-ti-wen-ti-dao-di-yo/

这个总结对于组合数与排列数的总结非常的到位。
组合数/排列数的根本原因在于1,2与2,1是不是一种情况,即是否有序。对于二维dp的定义两者是相等的,但是对于状态空间压缩后的情况,两种情况不等。
总结如下:二维dp的组合数问题和排列数问题 都可以交换嵌套的循环,因为子问题不会变化; 一维的dp组合数问题和排列数问题 不可以交换嵌套的循环,因为会改变子问题; 一维的dp组合数问题,交换嵌套的循环,子问题会变成排列数问题; 一维的dp排列数问题,交换嵌套的循环,子问题会变成组合数问题;
①据题目所求可以确定是组合数问题还是排列数问题,就可以决定dp表的横纵坐标分别表示什么了,之后无论用二维dp还是一维dp,状态的横纵坐标都是不变的 ②二维一维其实是看你的dp数组是一维还是二维决定的 ③如果写成了一维,那么两层循环的顺序不能改变----------一维的循环顺序(只能一行一行求解)为什么不能改变呢?因为如果改变循环顺序的话,变成了一列一列求,当求到第一列最后一行时,第一列前几行的数据已经被覆盖,当求第二列时,得到的数据是错的 ④如果写成了二维,那么两层循环的熟悉怒可以改变--------循环的顺序改变其实改变的的是一列一列求还是一行一行求,所以顺序是可以改变的(因为二维数组可以保存每一列和每一行的数据,但是一维的dp只能保存一行一行的保存数据)
从这个问题里面可以衍生成许多不同的问题,零钱兑换问题的I,II,爬楼梯问题。

背包问题继续强化

https://leetcode-cn.com/problems/coin-change-2/solution/gong-shui-san-xie-xiang-jie-wan-quan-bei-6hxv/

3.leetcode4月16个人赛
第三题,染色体染色的题目

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int getNumber(TreeNode* root, vector<vector<int>>& ops) {
    //鉴于二叉树中没有重复的值,可以额外设置标记
        //定义hashmap
        unordered_map<int,string>hp;
        int n=ops.size();
        for(int i=0;i<n;i++)
        {
            traverse(root,ops[i],hp);
        }
        int sum=0;
        for (auto iter = hp.begin(); iter !=hp.end(); ++iter) {
            if(iter->second=="red")
            {
                sum++;
            }
        }
        return sum;
    }
    void traverse(TreeNode* root,vector<int>& a,unordered_map<int,string>&hp)
    {
        if(root==nullptr)
        {
            return;
        }
        if(root->val>=a[1]&&root->val<=a[2] && a[0]==0)
        {
            //0是蓝色
            if(hp.count(root->val)==0)
            {
                hp[root->val]="blue";
            }
            else
            {
                    if(hp[root->val]=="red")
                    {
                        hp[root->val]="blue";
                    }
            }
        }
        if(root->val>=a[1]&&root->val<=a[2] && a[0]==1)
        {
            //1是红色
            if(hp.count(root->val)==0)
            {
                hp[root->val]="red";
            }
            else
            {
                    if(hp[root->val]=="blue")
                    {
                        hp[root->val]="red";
                    }
            }
        }
        traverse(root->left,a,hp);
        traverse(root->right,a,hp);
    }
};

死在了时间复杂度上,其实是自己糊涂了吗,第一遍便利都把信息都存储在了哈希表中,第二遍还去遍历,真是个傻逼。
第二遍去写,好像自己采用了能减小时间复杂度的方法,其实没有,循环的次数是一样的

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int getNumber(TreeNode* root, vector<vector<int>>& ops) {
    //鉴于二叉树中没有重复的值,可以额外设置标记
        //定义hashmap
        unordered_map<int,string>hp;
        int n=ops.size();
        traverse(root,hp);
        for(int i=0;i<n;i++)
        {
            for (auto iter = hp.begin(); iter !=hp.end(); ++iter)
            {
                if(iter->first>=ops[i][1]&&iter->first<=ops[i][2] && ops[i][0]==0)
                {
                    cout<<iter->second;
                  iter->second="blue";
                }
            if(iter->first>=ops[i][1]&&iter->first<=ops[i][2] && ops[i][0]==1)
                 {
                         iter->second="red";
                 }
             }
        }
        int sum=0;
        for (auto iter = hp.begin(); iter !=hp.end(); ++iter) {
            if(iter->second=="red")
            {
                sum++;
            }
        }
        return sum;
    }
    void traverse(TreeNode* root,unordered_map<int,string>&hp)
    {
        if(root==nullptr)
        {
            return;
        }
        hp[root->val]="chushi";
        traverse(root->left,hp);
        traverse(root->right,hp);
    }
};

其实上面的时间复杂度仍然没有变化。时间复杂度为:树节点的个数乘上ops数组行的数目

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值