当前位置: 首页 > news >正文

算法专题(五):模拟

目录

一、替换所有的问号

1.1 题目

1.2 思路

1.3 代码

二、提莫攻击 

2.1 题目

2.2 思路

2.3 代码

三、Z 字形变换

3.1 题目

3.2 思路

3.3 代码

四、外观数列 

4.1 题目

4.2 思路

4.3 代码

五、数青蛙 

5.1 题目

5.2 思路

5.3 代码


每道题目的标题均是该题的传送门!

模拟算法通俗的讲就是比葫芦画瓢,思路比较简单,考验的是代码能力!

一、替换所有的问号

1.1 题目

1.2 思路

纯模拟。从前往后遍历整个字符串,找到问号之后,就用 a ~ z 的每一个字符去尝试替换即可。

1.3 代码

class Solution {
public:
    string modifyString(string s) 
    {
        int n = s.size();
        for(int i = 0;i < n;i++)
        {
            if(s[i] == '?')
                for(int ch = 'a';ch <= 'z';ch++)
                    if((i==0 || ch != s[i-1]) && (i==n-1 || ch != s[i+1]))
                    {
                        s[i] = ch;
                        break;
                    }
        }    
        return s;
    }
};

二、提莫攻击 

2.1 题目

2.2 思路

模拟 + 分情况讨论。
计算相邻两个时间点的差值:
        i. 如果差值大于等于中毒时间,说明上次中毒可以持续 duration 秒;
        ii. 如果差值小于中毒时间,那么上次的中毒只能持续两者的差值。

2.3 代码

class Solution {
public:
    int findPoisonedDuration(vector<int>& timeSeries, int duration) 
    {
        int n = timeSeries.size();
        int ret = 0;
        for(int i = 1;  i < n; i++)
        {
            if(timeSeries[i] - timeSeries[i-1] < duration)
                ret += timeSeries[i] - timeSeries[i-1];
            else
                ret += duration;
        }
        ret += duration;
        return ret;
    }
};

三、Z 字形变换

3.1 题目

3.2 思路

找规律,用 row 代替行数,row = 4 时画出的 N 字形如下:
0         2row - 2                         4row - 4
1         2row - 3      2row - 1      4row - 5     4row - 3
2         2row-4        2row           4row - 6     4row - 2
3         2row + 1                        4row - 1
不难发现,数据是以 2row - 2 为一个周期进行规律变换的。将所有数替换成用周期来表示的量:
第一行的数是:0, 2row - 2, 4row - 4;
第二行的数是:1, (2row - 2) - 1, (2row - 2) + 1, (4row - 4) - 1, (4row - 4) + 1;
第三行的数是:2, (2row - 2) - 2, (2row - 2) + 2, (4row - 4) - 2, (4row - 4) + 2;
第四行的数是:3, (2row - 2) + 3, (4row - 4) + 3。
可以观察到,第一行、第四行为差为 2row - 2 的等差数列;第二行、第三行除了第一个数取值为行数,每组下标为(2n - 1, 2n)的数围绕(2row - 2)的倍数左右取值。
以此规律,我们可以写出迭代算法。

3.3 代码

注意一下n==1的时候

class Solution {
public:
    string convert(string s, int numRows) 
    {
        if(numRows == 1)
            return s;
        string ret;
        int d = 2 * numRows - 2, n = s.size();
        //先处理第一行
        for(int i = 0; i < n;i += d)
            ret += s[i] ;
        //处理中间行
        for(int k = 1; k < numRows - 1; k++)
        {
            for(int i = k,j = d-k;i < n || j < n; i+=d,j+=d)
            {
                if(i < n)
                    ret += s[i];
                if(j < n)
                    ret += s[j];
            }
        }
        //处理最后一行
        for(int i = numRows -1;i < n; i+=d)
            ret += s[i];
        return ret;
    }
};

四、外观数列 

4.1 题目

4.2 思路

所谓外观数列,其实只是依次统计字符串中连续且相同的字符的个数。依照题意,依次模拟即
可。

4.3 代码

class Solution {
public:
    string countAndSay(int n) 
    {
        string ret = "1";

        for(int i = 1; i < n; i++)
        {
            string tmp;
            int left = 0,right = 0;
            while(right < ret.size())
            {
                while(right < ret.size() && ret[left]==ret[right])
                    right++;
                tmp += to_string(right-left) + ret[left];
                left = right;
            }
            ret = tmp;
        }
        return ret;
    }
};

五、数青蛙 

5.1 题目

5.2 思路

模拟青蛙的叫声。
        ◦ 当遇到 'r' 'o' 'a' 'k' 这四个字符的时候,我们要去看看每一个字符对应的前驱字符,有没有青蛙叫出来。如果有青蛙叫出来,那就让这个青蛙接下来喊出来这个字符;如果没有,直接返回 -1;
        ◦ 当遇到 'c' 这个字符的时候,我们去看看 'k' 这个字符有没有青蛙叫出来。如果有,就让这个青蛙继续去喊 'c' 这个字符;如果没有的话,就重新搞一个青蛙。

5.3 代码

class Solution {
public:
    int minNumberOfFrogs(string croakOfFrogs) 
    {
        string t = "croak";
        int n = t.size();
        vector<int> hash(n);
        unordered_map<char,int> arr; [x, x这个字符对应的下标]
        for(int i = 0; i < n; i++)
            arr[t[i]] = i;
        
        for(auto ch : croakOfFrogs)
        {
            if(ch == 'c')
            {
                if(hash[n-1] != 0)
                    hash[n-1]--;
                hash[0]++;
            }
            else
            {
                int i = arr[ch];
                if(hash[i-1] == 0)
                    return -1;
                hash[i]++;
                hash[i-1]--;
            }
        }
        for(int i = 0; i < n-1;i++)
        {
            if(hash[i] != 0 )
                return -1;
        }
        return hash[n-1];
    }
};


本篇完,下篇见!

相关文章:

  • Maven核心包:maven-resolver-api
  • 海鲜水产行业wordpress外贸主题
  • linux grub文件丢失
  • C语言之共用体
  • 腾讯混元大模型简介
  • LVPECL(Low Voltage Positive Emitter-Coupled Logic)电平详解
  • Wireshark:在 显示过滤器中“加入条件”过滤后,出现其他类型的数据包,为什么?
  • 在Android中,子线程可以更新UI吗
  • 刷题练习笔记
  • Leetcode-1278.Palindrome Partitioning IV [C++][Java]
  • Word 小黑第18套
  • 《Operating System Concepts》阅读笔记:p309-p330
  • 开启云服务器ubuntu22.04的远程桌面,支持Windows远程连接 - 开启XRDP支持
  • TypeScript装饰器
  • An effective algorithm for peptide de novo sequencing from MS/MS spectra
  • 二分算法刷题
  • 【NLP】 4. NLP项目流程与上下文窗口大小参数的影响
  • llama-factory笔记
  • python二级复习(1)
  • 编程题-第k个语法符号(中等)
  • Pc端网站是什么意思/公司推广策划
  • 如何做网站百科/百度极速版app下载安装
  • 四川网站建设seo/常见的网站推广方式有哪些
  • 网件路由器app/seo网站优化培训厂家报价
  • 福州最新消息/seo站群优化
  • jq网站特效插件/软文发稿公司