LeetCodeGOGOGO刷题记05——备战Amazon(打表,dp,刷刷刷)

19 篇文章 0 订阅
5 篇文章 0 订阅
本文记录了作者在LeetCode上刷题的过程,涉及题目包括Two Sum、Prison Cells After N Days、Find Words That Can Be Formed by Characters和Number of Dice Rolls With Target Sum。对于Two Sum,作者采用双循环暴力解法,而957题通过观察发现每14回合一循环,利用打表优化。在1160题中,通过记录字母集情况匹配单词。最后一题1155题,作者使用动态规划(DP)解决骰子组合问题。通过刷题,作者感受到DP等算法在解题中的威力。
摘要由CSDN通过智能技术生成

1. Two Sum

难度:

Easy

思路:

刷到了leetcode的第一道题,求两数和等于特定值的pair,考虑到题号和难度,直接双循环暴力,O(n^{^2})解决

什么?哈希优化?还有啥啥啥优化?这种题还优化个啥?赶紧看下一题去,别在水题上浪费时间!

代码:

/*
Author Owen_Q
*/

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        //sort(nums.begin(),nums.end());
        int n = nums.size();
        vector<int> re;
        re.clear();
        bool con = true;
        for(int i=0;con&&i<n;i++)
        {
            for(int j=0;con&&j<n;j++)
            {
                if(i==j)
                    continue;
                if(nums[i]+nums[j]==target)
                {
                    re.push_back(i);
                    re.push_back(j);
                    con = false;
                    break;
                }
            }
        }
        return re;
    }
};

957. Prison Cells After N Days

难度:

Medium

思路:

模拟线性监狱情况:两端房间不能为空;两侧房间同时为空或为满时,当前房间下一回合填满;否则,当前房间下一回合为空。模拟实现n回合后监狱情况。

那么直接模拟就好啦,注意到n可能会很大,打表找规律发现每14回合一循环,于是最多直接模拟前14回合即可。

最后一个小细节就是当n=0时是初始情况,此时两端房间可以为满,因此应当以1~14作为一个循环节而不是0~13

代码:

/*
Author Owen_Q
*/

class Solution {
public:
    vector<int> prisonAfterNDays(vector<int>& cells, int N) {
        N %= 14;
        if(N==0)
            N=14;
        while(N--)
        {
            int now[8];
            for(int i=1;i<7;i++)
            {
                if(cells[i-1]==cells[i+1])
                    now[i] = 1;
                else
                    now[i] = 0;
                cout << now[i] << " ";
            }
            cout << endl;
            for(int i=1;i<7;i++)
                cells[i] = now[i];
            cells[0] = 0;
            cells[7] = 0;
        }
        return cells;
    }
};

1160. Find Words That Can Be Formed by Characters

难度:

Easy

思路:

给定字典和字母集,统计字典中有多少单词可以由字母集构成

那直接开个数组记录字母集情况,然后对应字典中的单词依次匹配就好啦

代码:

/*
Author Owen_Q
*/

lass Solution {
public:
    int countCharacters(vector<string>& words, string chars) {
        int col[26];
        int now[26];
        int sum = 0;
        memset(col,0,sizeof col);
        for(char i:chars)
            col[i-'a']++;
        int n = words.size();
        for(string s:words)
        {
            bool ok = true;
            memset(now,0,sizeof now);
            for(char i:s)
            {
                int nowpos = i-'a';
                now[nowpos]++;
                if(now[nowpos]>col[nowpos])
                    ok = false;
            }
            if(ok)
                sum += s.size();
        }
        return sum;
    }
};

1155. Number of Dice Rolls With Target Sum

难度:

Medium

思路:

求d个f面的骰子总和为特定值target的不同情况数

不难发现,每次增加一个骰子整体情况都可以形成一种递推

于是……dp来袭,好久没见到dp的题了

来个二维dp,第一维表示骰子数a,第二维表示达到特定的目标b,那dp[a][b]就用来表示用a个骰子得到总和为b的不同方案数

开始转移,每次增加一个新骰子,每个不同骰子的面都可以增加一种转移情况,即dp[a][b]可以由dp[a-1][b-k]转移来,而这里的k就是单个骰子可能得到的数

代码:

/*
Author Owen_Q
*/

class Solution {
public:
    int numRollsToTarget(int d, int f, int target) {
        if(target>d*f||target<d)
            return 0;
        memset(dp,0,sizeof dp);
        for(int i=1;i<=f;i++)
            dp[1][i] = 1;
        for(int i=2;i<=d;i++)
            for(int j=1;j<=f;j++)
                for(int k=j+1;k<=target;k++)
                    dp[i][k] = (dp[i][k] + dp[i-1][k-j]) % mod;
        return dp[d][target];
    }
private:
    const int mod = 1e9+7;
    int dp[50][1010];
};

感觉这几天刷题还是挺有效果的,当我不到一周前开启这一轮刷题的时候

到现在我做完上面那道dp时

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值