【刷题】模拟

模拟算法:题目中已经告诉应该怎么做了,只需要模拟即可,思路比较简单,比较考察代码能力。

一般先在草稿纸上模拟流程,如果直接写代码,容易忽视细节,并且不容易调试!

优化策略:找规律!

Z 形变换

 Z 字形变换

  • 暴力模拟
  • 找规律
// 暴力模拟
class Solution {
public:
    string convert(string s, int numRows) {
        vector<vector<char>> v(numRows, vector<char>(s.size()));
        int j = 0, k = 0; // j 为行,k 为列
        int count = 0;
        int i = 1;
        v[j][k] = s[0];
        while (i < s.size())
        {
            while (j + 1 < numRows)
            {
                j++;
                v[j][k] = s[i];
                if (i < s.size()) i++;
                else break;
            }
            if(j == 0) 
            {
                k++;
                v[j][k] = s[i];
                if (i < s.size()) i++;
            }
            while (j > 0)
            {
                j--, k++;
                if(k < s.size()) 
                {
                    v[j][k] = s[i];
                }
                if (i < s.size()) i++;
                else break;
            }
        }
        string str;
        for (int i = 0; i < numRows; i++)
        {
            for (int j = 0; j < s.size(); j++)
            {
                if (v[i][j] != 0) str.push_back(v[i][j]);
            }
        }
        return str;
    }
};
// 找规律
class Solution {
public:
    string convert(string s, int numRows) {
        // 模拟类题目的优化思路:找规律
        if(numRows == 1) return s;
        int d = 2 * numRows - 2; // 计算公差  第一行和最后一行元素相隔的距离
        int n = s.size();
        string ret;
        // 处理第一行
        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;
    }
};

数青蛙

数青蛙

  • 暴力模拟
  • 哈希模拟
// 暴力模拟
class Solution {
public:
    int minNumberOfFrogs(string s) {
        int hash[26] = { 0 };
        int n = s.size();
        for(int i = 0; i < n; i++)
        {
            if(s[i] == 'c'){
                if(hash['k'-'a'] == 0)//没有青蛙叫结束了
                    hash['c' - 'a']++;
                else
                {
                    hash['c' - 'a'] ++;
                    hash['k' - 'a'] --; // 有 叫结束的青蛙
                }
            }
            else if(s[i] == 'r'){
                if(hash['c' - 'a'] != 0)
                {
                    hash['c' - 'a'] --;
                    hash['r' - 'a'] ++;
                }
                else return -1;
            } 
            else if(s[i] == 'o'){
                if(hash['r' - 'a'] != 0)
                {
                    hash['r' - 'a'] --;
                    hash['o' - 'a'] ++;
                }
                else return -1;
            } 
            else if(s[i] == 'a'){
                if(hash['o' - 'a'] != 0)
                {
                    hash['o' - 'a'] --;
                    hash['a' - 'a'] ++;
                }
                else return -1;
            } 
            else if(s[i] == 'k'){
                if(hash['a' - 'a'] != 0)
                {
                    hash['a' - 'a'] --;
                    hash['k' - 'a'] ++;
                }
                else return -1;
            } 
        }
        if(hash['k' - 'a'] == 0) return -1;
        if(hash['c' - 'a'] != 0 || hash['r' - 'a'] != 0 || 
        hash['o' - 'a'] != 0 || hash['a' - 'a'] != 0) return -1;
        return hash['k' - 'a'];
    }
};
// 哈希模拟
// hash 中存按 "croak" 顺序的字符对应的字符个数 
// unordered_map 中存字符和字符对应于 hash 中的下标
class Solution {
public:
    int minNumberOfFrogs(string s) {
        string t = "croak";
        int n = t.size();
        vector<int> hash(n);
        unordered_map<char ,int> index; // first 存字符; second 存这个字符对应的下标
        for(int i = 0; i < n; i++) index[t[i]] = i;
        for(int i = 0; i < s.size(); i++)
        {
            if(s[i] == 'c')
            {
                if(hash[n - 1] == 0) hash[index[s[i]]]++;
                else 
                {
                    hash[n - 1]--;
                    hash[index[s[i]]]++;
                }
            }

            else
            {
                int k = index[s[i]]; // k为下标
                if(hash[k - 1] != 0)
                {
                    hash[k - 1]--;
                    hash[k]++;
                }
                else return -1;
            }
        }
        for(int i = 0; i < n - 1; i++)
        {
            if(hash[i] != 0) return -1;
        }
        return hash[n - 1];
    }
};

外观数列 

外观数列

用递归来模拟

class Solution {
public:
    void _countAndSay(int n, string& str)
    {
        if(n == 1) 
        {
            str += "1";
            return;
        }
        _countAndSay(n - 1, str);
        int count = 0;
        string s_ret;
        for(int i = 0; i < str.size(); i++)
        {
            count = 1;
            while(i + 1 < str.size() && str[i] == str[i + 1])
            {
                count++;
                i++;
            }
            s_ret += ('0' + count);
            s_ret += str[i];
        }
        str = s_ret;
    }
    string countAndSay(int n) {
        string str;
        _countAndSay(n, str);
        return str;
    }
};

替换所有的问号

替换所有的问号

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

提莫攻击

提莫攻击

class Solution {
public:
    int findPoisonedDuration(vector<int>& timeSeries, int duration) {
        int count = 0; // 中毒总秒数
        int ret = duration;
        for(int i = 0; i < timeSeries.size(); i++)
        {
            for(int j = 0; j < duration; j++)
            {
                if(i + 1 < timeSeries.size() && timeSeries[i] + j != timeSeries[i + 1])
                {
                    count++;
                } 
                else break;
            }
            ret = duration;
        }
        count += duration;
        return count;
    }
};
  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值