LeetCode日记20200214

LeetCode日记2020.2.14


刷题看来得适量,要不然越刷越糊涂@_@

316 去除重复字母(hard)

class Solution {
public:
    string removeDuplicateLetters(string s) {
        string res;
        for(int i=0;i<s.size();++i)
        {
            auto pos= res.find(s[i]);
            if(pos==string::npos)
            {
                while(!res.empty()&&res.back()>=s[i]&&s.find(res.back(), i)!=string::npos)
                    res.pop_back();

                res.append(1, s[i]);
            }
        }
        return res;
    }
};

120 三角形最小路径和(mid)

基本动态规划

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        vector<int> dp(triangle.back());
        for(int i = triangle.size() - 2; i>=0; --i)
        {
            for(int j = 0;j<triangle[i].size(); ++j)
            {
                dp[j] = triangle[i][j] + min(dp[j], dp[j+1]);
            }
        }
        return dp[0];
    }
};

16 最接近三数之和(mid)

双指针还能这么用!

class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        sort(nums.begin(), nums.end());
        int optSum = nums[0] + nums[1] + nums[2];
        for(int i=0; i<nums.size()-2; ++i)
        {
            int beg = i + 1, End = nums.size()-1;
            while(beg < End)
            {
                int sum = nums[beg] + nums[End] + nums[i];
                if(sum == target)
                    return target;
                else
                {
                    if(abs(optSum - target)>abs(sum-target))
                        optSum = sum;

                    sum>target?--End:++beg;
                }
            }
        }
        return optSum;
    }
};

39 组合总和(mid)

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        return combinaSum(candidates.cbegin(), candidates.cend(), target);
    }

    vector<vector<int>> combinaSum(vector<int>::const_iterator beg, 
        vector<int>::const_iterator End, int target)
    {
        vector<vector<int>> res;
        if(beg == End || target <= 0)
            return res;

        while(beg != End)
        {
            int fir = *beg;
            if(fir == target)
                res.emplace_back(1, fir);

            auto combi = combinaSum(beg, End, target-(*beg));
            for(auto& c: combi)
            {
                res.push_back(std::move(c));
                res.back().push_back(fir);
            }
            ++beg;
        }
        return res;
    }
};

1079 活字印刷(mid)

class Solution {
public:
    int numTilePossibilities(string tiles) {
        map<char, int> cM;
        vector<int> ps;
        for(auto c: tiles)
        {
            auto iter = cM.find(c);
            if(iter == cM.end())
            {
                cM[c] = ps.size();
                ps.push_back(1);
            }
            else
                ++ps[iter->second];
        }

        deque<vector<int>> deq;
        deq.push_back(ps);
        int n = ps.size();
        int cnt = 0;
        while(!deq.empty())
        {
            auto t = deq.front();
            deq.pop_front();
            for(int i=0;i<n;++i)
            {
                if(t[i] != 0)
                {
                    auto cpyT = t;
                    --cpyT[i];
                    deq.push_back(cpyT);
                    ++cnt;
                }
            }
        }
        return cnt;
    }
};

77 组合(mid)

class Solution {
public:
    vector<vector<int>> combine(int n, int k) {
        if(n == 0 || n < k)
            return vector<vector<int>>();

        vector<vector<int>> res;
        if(k == 1)
        {
            for(int i = 1;i<=n;++i)
            {
                res.push_back(vector<int>(1, i));
            }
            return res;
        }

        for(int i = n; i>=k; --i)
        {
            auto combi = combine(i-1, k-1);
            for(auto& c: combi)
            {
                res.push_back(std::move(c));
                res.back().push_back(i);
            }
        }
        return res;
    }
};

22 括号生成(mid)

居然可以转化为DP!

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        vector<vector<string>> dp;
        dp.push_back(vector<string>(1, string("")));
        dp.push_back(vector<string>(1, string("()")));
        for(int i=2;i<=n;++i)
        {
            dp.push_back(vector<string>());
            for(int j=0;j<i;++j)
            {
                for(const auto& p: dp[j])
                {
                    for(const auto& q: dp[i-j-1])
                    {
                        dp.back().push_back(string("(") + p + string(")") + q);
                    }
                }
            }
        }
        return dp[n];
    }
};

左右括号匹配枚举

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        vector<string> res;
        geneP(res, 0, 0, n);
        return res;
    }

    void geneP(vector<string>& res, int left, int right, int n)
    {
        if(left == right && left == n)
        {
            res.push_back(descr);
            return;
        }

        if(n>left)
        {
            descr.append(1, '(');
            geneP(res, left + 1, right, n);
            descr.pop_back();
        }

        if(right < left)
        {
            descr.append(1, ')');
            geneP(res, left, right + 1, n);
            descr.pop_back();
        }
    }

    string descr;
};

46 全排列(mid)

class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        if(nums.empty())
            return vector<vector<int>>();
        
        if(nums.size() == 1)
            return vector<vector<int>>(1, nums);

        vector<vector<int>> res;
        for(int i=0;i<nums.size();++i)
        {
            vector<int> sub;
            int h = nums[i];
            copy_if(nums.cbegin(), nums.cend(), back_inserter(sub), [h](int i){return i!=h;});
            auto se = permute(sub);
            for(auto& s: se)
            {
                res.push_back(std::move(s));
                res.back().push_back(h);
            }
        }
        return res;
    }
};
1. 项目背景基于项目提供的汽车相关数据,通过聚类分析的方法实现汽车产品聚类,以构建汽车产品画像、分析产品定位、完成汽车竞品分析等要求。2. 项目数据项目提供的汽车数据包括26个字段共205条数据,数据文件为“car_price.csv” 26个字段可以划分为类别型变量和数值型变量两种,包括汽车的长/宽/高、汽车净重、燃油系统、燃油类型、驱动类型、峰值转速、里程数、汽车价格等。3. 项目要求通过聚类的方法构建汽车产品画像、分析不同类别汽车的产品定位,寻找Volkswagen大众汽车的竞品品牌。4. 项目思路第一步:数据字段理解根据项目所提供的数据,对数据中26个字段进行理解。结合汽车行业的相关知识,26个字段可以大致归为两类:第一类是车辆自身属性(如燃油系统、燃油类型、汽缸数、峰值转速、汽车长宽高等);第二类是车辆的市场属性(如车辆名称、车辆价格、风险评估等级)。26个字段主要分为数值型变量和类别型变量两类。第二步:原始数据描述性统计及变量分布可视化对原始数据进行描述性统计并对数据中的字段分布进行可视化(详情见主文档)。通过对原始数据的观察,数据不存在缺失值、不存在重复值,“CarName”字段存在部分车辆品牌名称错误的情况。第三步:确定聚类方法,明确聚类要求通过对原始数据的变量观察,该数据变量主要为数值型变量和类别型变量两类,且类别型变量数量较多,常用的K-means聚类只能分析数值型变量,无法考虑类别型变量所包含的信息。二阶段聚类法适用于包含数值型和类别型变量的混合数据,因此考虑使用二阶段聚类法分析数据。二阶段聚类法的要求是:类别型变量符合多项式分布(即变量的值分属几个类别);数值型变量间要相互独立,且数值型变量近似服从正态分布。项目所给出的数据中,类别型变量符合多项式分布,因此仅需进一步观察并处理数值型变量。第四步:特征工程数据清洗与新变量生成。原始数据指给出了车辆的名称,没有给出车辆所属品牌,结合最终聚类分析的需要,根据“CarName”字段提取出车辆所属品牌信息,命名为“brand”。同时对品牌名称中的错误拼写进行清洗。变量相关性分析与可视化。由于二阶段聚类要求数值型变量间相互独立,所以需要对数值型变量间的相关性进行查看与处理。相关性分析结果表示14个数值型变量之间存在高相关性情况,需要结合汽车知识背景与变量特征进行进一步处理。高相关变量的处理——“highwaympg”和“citympg”呈高度正相关。其实不管是高速mpg还是城市mpg,其本质都是mpg指标,而且通过观察数据,二者之间的差异较小(极值、均值),因此考虑将二者合并为一个指标'mpg',计算方式为取二者均值:mpg=(highwaympg+citympg)/2;高相关性变量的处理——“price”变量与其余变量产生高相关性的频数最多,可能是因为车辆自身属性和配置的变动会直接影响着车辆的市场价格。此外,与其他变量相比,price属性属于车辆的市场销售属性(而非车辆自身属性),在聚类中更适合作为类别型变量,对车辆的价位进行划分,因此,考虑将price变量转换为类别型变量,按照其价格分布划分为Low price(<=10000), medium price(10000-20000), high price(>20000)三类;高相关性变量的处理——对于其余数值型变量,变量数目较多且多个变量之间存在相关性,因此考虑使用因子分析对数值型变量进行降维,以减少数值型变量的数目并使变量间相互独立。第五步:数值型变量因子分析结果(基于SPSS实现)利用SPSS对数值型变量进行因子分析,KMO值>0.8,巴特利球形检验p值=0,说明参与因子分析的变量间存在相关性,可以进行因子分析。最终得到两个因子。第一个因子包括:车长、车宽、车净重、引擎尺寸、车轴距、mpg、马力、车内径比。简单将该因子归纳为车辆截面与马力因子;第二个因子包括:车高、峰值转速、车压缩比。简单将该因子归纳为车辆垂面与转速因子;第六步:两阶段聚类及结果(基于SPSS实现)对处理后的数据进行两阶段聚类,最终将205辆车聚为两类。根据SPSS聚类结果,第一类中包含120条车辆数据,占总数据的58.5%;第二类中包含85条车辆数据,占总数据的41.5%。两类簇数据规模近似,没有过大或过小的类簇。根据SPSS聚类结果,聚类质量属于“良好”范围,仍有进一步改进和优化的空间。根据SPSS聚类结果,显著区分两类类簇的变量(重要性>0.6)按重要性大小排序依次是驱动类型、燃油系统、车辆截面与马力因子、价格范围。汽车产品画像与产品定位根据区分类簇的四个重要标签来对数据中的汽车产品进行产品画像与产品定位。第一类画像:驱动类型多为fwd(前轮驱动),燃油系统多
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值