算法 | 模拟

目录

替换所有的问号 

题解:

提莫攻击

 题解:

Z字形变换

题解:

外观数列

题解:

数青蛙

题解:


替换所有的问号 

1576. 替换所有的问号 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/replace-all-s-to-avoid-consecutive-repeating-characters/description/

题解:

遍历字符串,找到字符串中的 ?,把 ?替换成字母,且替换后的字母不能和 ?的前一个字符和后一个字符相同。

这道题主要是边界的处理,如果字符串的第一个字符为 ?,那么替换后的字符只需要和后一个字符不相同,如果字符串的最后一个字符为 ?,替换后的字符只需要和前一个字符不相同否则会越界访问

下面的 if 写的很妙,很好的处理了边界情况!

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++)//26个字母逐个尝试
                {
                    if((i==0 || s[i-1]!=ch)&&(i==n-1 || s[i+1]!=ch))//与前一个、后一个字母均不相等
                    {
                        s[i]=ch;
                        break;
                    }
                }
            }
        }
        return s;
    }
};

提莫攻击

495. 提莫攻击 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/teemo-attacking/description/

 题解:

主要还是处理边界,不要越界访问了!

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字形变换

6. Z 字形变换 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/zigzag-conversion/description/

题解:

本题只需要找出 Z 字形变换的规律就可以得到解。

Z字形变换后,观察第一行和最后一行的下标,发现下标的间隔都是固定的,

间隔 d = 2*numRows-2

观察Z字形变换后的中间 k 行,发现在每一行中,它们是间隔着有规律的,是间隔着递增的,

比如 numRows=3 时,在第2行中,1+3=4=d,5=1+d,7=3+d,9=5+d,11=7+d

numRows=4 时,在第 2 行中,1+5=6=d,7=1+d,11=5+d,13=7+d

                            在第 3 行中,2+4=6=d,8=2+d,10=4+d


 ​​首先我们需要找到第 k 行( k 从 1 开始)的两个起始下标 i 和 j,i+j = d,而 i = k,则 j = d-k,之后 i +=d , j += d,注意边界的处理!

class Solution {
public:
    string convert(string s, int numRows) {
        if(numRows==1) return s;

        int d=2*numRows-2,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)
            {
                //注意for循环的条件判断为或
                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;
    }
};

外观数列

38. 外观数列 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/count-and-say/description/

题解:

这道题主要是理解题目的意思。

给了一个初始字符串 1,按照 “ 1 个 1 ”,把字符串压缩为 “ 11 ”,再继续按照 “ 2 个 1”,把字符串压缩为 “ 21 ”,继续按照 “ 1 个 2 ,1 个 1 ” ,把字符串压缩为 “ 1211 ”,以此类推即可。

用双指针来遍历字符串,找出相同数字的个数即可。

class Solution {
public:
    string countAndSay(int n) {
        string s="1";
        while(--n)
        {
            string tmp;
            int len=s.size();
            for(int left=0,right=0;right<len;)
            {
                while(right<len && s[left]==s[right]) ++right;
                tmp+=(to_string(right-left)+s[left]);
                left=right;
            }
            s=tmp;
        }
        return s;
    }
};

数青蛙

1419. 数青蛙 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/minimum-number-of-frogs-croaking/description/

题解:

这道题的意思就是 croak 这个单词会在字符串中交叉着出现,但是字符串里面一定只有 croak 这五个字母,否则就是无效的字符串。

我们遍历字符串:

  • 如果出现的是 c,那么需要判断它是由一只新的青蛙唱的,还是可以由已经唱完的青蛙来唱,唱完的青蛙上一次唱的一定是 k,所以如果 k 的次数不为 0,那么就可以由已经唱完的青蛙来唱,否则就只能由一只新的青蛙来唱。
  • 如果出现的是  r、o、a、k,那么则需要判断它们的前驱字符有没有唱,如果唱过了,说明字符串的 croak 没有缺字母,如果没唱过,则说明 croak 缺字母了,字符串是无效的,返回 -1。
  • 利用数组来标记字符有没有唱过,唱过了就标记唱过的次数,没唱过就是 0.

    代码主要学习用数组和哈希表建立一个映射关系,映射关系如下:

class Solution {
public:
    int minNumberOfFrogs(string croakOfFrogs) {
        string t="croak";
        int n=t.size();
        vector<int> hash(n);//哈希表,记录字母出现的次数
        unordered_map<char,int> index;
        for(int i=0;i<n;i++)
            index[t[i]]=i;//c->0,r->1,o->2,a->3,k->4
        for(auto x:croakOfFrogs)
        {
            if(x=='c')
            {
                if(hash[n-1]!=0)    hash[n-1]--;
                hash[0]++;
            }
            else
            {
                int i=index[x];
                if(hash[i-1]==0) return -1;//不配对
                hash[i-1]--;    hash[i]++;
            }
        }
        for(int i=0;i<n-1;i++) 
        {
            if(hash[i]!=0)  return -1;
        }   
        return hash[n-1];
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值