2022-01-05每日刷题打卡

2022-01-05每日刷题打卡

力扣——每日一题

1576. 替换所有的问号

给你一个仅包含小写英文字母和 ‘?’ 字符的字符串 s,请你将所有的 ‘?’ 转换为若干小写字母,使最终的字符串不包含任何 连续重复 的字符。

注意:你 不能 修改非 ‘?’ 字符。

题目测试用例保证 除 ‘?’ 字符 之外,不存在连续重复的字符。

在完成所有转换(可能无需转换)后返回最终的字符串。如果有多个解决方案,请返回其中任何一个。可以证明,在给定的约束条件下,答案总是存在的。

示例 1:

输入:s = “?zs”
输出:“azs”
解释:该示例共有 25 种解决方案,从 “azs” 到 “yzs” 都是符合题目要求的。只有 “z” 是无效的修改,因为字符串 “zzs” 中有连续重复的两个 ‘z’ 。

一开始是准备了一个26个字母的字符串,和一个随机数生成的函数,这个函数接收两个参数,这两个参数是‘?’符号左右两边的字母在26字母中的位置,然后我们随机生成0~25的数字,只要不等于这两个数就算生成成功,如果有相等的就把这个数再生成一遍,直到不相等为止,把随机数返回给主函数。

主函数里先判断一下s的长度,如果长度为1且那个字符就是‘?’,我们就随便返回一个字母即可,然后for循环开始遍历s,每次遇到’?‘符号时,把他左右两边的字母-’a’得到它们在26字母中的位置,并且通过这两个数调用生成随机数的函数,再通过得到的随机数根据一开始准备好的26字母字符串,以随机数作为下标从里面取一个字母赋给‘?’。遍历完后返回s即可。

class Solution {
public:
    int rand_num(int a,int b)
    {
        int c;
        do c=rand()%25;while(c==a||c==b);
        return c;
    }
    string modifyString(string s) {
        string word="abcdefghijklmnopqrstuvwxyz";
        int n =s.size();
        if(n==1&&s[0]=='?')return "a";
        for(int i=0;i<n;i++)
        {
            if(s[i]=='?')
            {
                if(i==0)s[i]=word[rand_num(-1,s[i+1]-'a')];
                else if(i==n-1)s[i]=word[rand_num(-1,s[i-1]-'a')];
                else s[i]=word[rand_num(s[i-1]-'a',s[i+1]-'a')];
            }
        }
        return s;
    }
};

但这解法有些许复杂了,我们还有更简单的方法。

我们知道,想要三个连续字符使得他们相邻的字符不出现重复,最多只需要三个字符(这里我们取‘a’,‘b’,‘c’),简单点可以是aba,最复杂也不过abc,所以我们不需要26个字母,只需要三个字母即可。

我们遍历s字符串,遇到’?'字符后开始for循环,在abc三个字符中循环,只要循环到的字符不同时等于’?‘字符相邻的字母,我们就把循环到的字符赋给’?‘。遍历结束后返回s。

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

飞书——每日一题

79. 单词搜索

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例 1:

word2.jpg (322×242) (leetcode.com)

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true

深度优先搜索,先在主函数里确定出发点,遍历一遍board,看哪个格子里的元素和word的第一个元素相同,相同就以当前位置为起点开始dfs,准备两个方向数组,一个dx一个dy,两个一起再配合dfs函数里的for循环让元素在相邻上下左右的格子里移动,为确保格子不被重复利用,我们再准备一个和board相同大小的bool类型二维数组,初始都设置为false,当一个格子里的元素被利用过后,把bool数组里相应位置的元素改为true,以让我们知道这格子元素被利用过了。在dfs的for中,当遍历到board有元素和word当前遍历到的字符元素相等,就把那个位置送去下一次dfs,以此往复,当word被全部找到,返回true。要是在主函数里遍历所有起始点也找不到相同元素,返回false。

class Solution {
public:
    int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
    string str;
    vector<vector<char>>v;
    bool flag[7][7];
    bool a=false;
    bool exist(vector<vector<char>>& board, string word) {
        str=word;
        v=board;
        for(int i=0;i<board.size();i++)
        {
            for(int j=0;j<board[0].size();j++)
            {
                if(board[i][j]==word[0])
                {
                    flag[i][j]=true;
                    dfs(1,i,j,board.size(),board[0].size());
                    if(a)return a;
                    flag[i][j]=false;
                }
            }
        }
        return a;
    }
    void dfs(int u,int i,int j,int n,int m)
    {
        if(a||u==str.size())
        {
            a=true;
            return;
        }
        for(int d=0;d<4;d++)
        {
            if(i+dx[d]>=0&&i+dx[d]<n&&j+dy[d]>=0&&j+dy[d]<m&&!flag[i+dx[d]][j+dy[d]]&&
                v[i+dx[d]][j+dy[d]]==str[u])
                {
                    u++;
                    flag[i+dx[d]][j+dy[d]]=true;
                    dfs(u,i+dx[d],j+dy[d],n,m);
                    if(a)return;
                    u--;
                    flag[i+dx[d]][j+dy[d]]=false;
                }
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值