打卡leetcode第13天

1.词典中最长的单词

【题目】

给出一个字符串数组 words 组成的一本英语词典。返回 words 中最长的一个单词,该单词是由 words 词典中其他单词逐步添加一个字母组成。

若其中有多个可行的答案,则返回答案中字典序最小的单词。若无答案,则返回空字符串。

【分析】

题目是说对每个单词w,如果w的所有前缀都在字典中,那么单词w是一个解。
题目要找最长,同时字典序最小的单词w。

【代码】

class Solution {
public:
    string longestWord(vector<string>& words) {
        unordered_set<string> S(words.begin(),words.end());
        string ans;
        for(auto w : words){
            bool ok = true;
            for(int i=0;i<w.size()-1;++i){
                string prefix = w.substr(0,i+1);//单词w的所有前缀      
                if(!S.count(prefix)){
                    ok = false;
                    break;
                }
            }
            if(ok){
                if(ans.empty() || w.size() > ans.size() 
                    || w.size() == ans.size() 
                    && w < ans){
                        ans = w;
                    }
            }
        }
        return ans; 
    }
};

2.无重复字符的最长子串

【题目】

【思路】

i为左窗口, j为右窗口;
因为每次我要让右窗口移动, 所以用for循环, 当右窗口移动到len时停止;

再用一个S【】数组去标记每个字符在 窗口 出现的次数,当S[a] == 2;
代表a字符出现了2次, 这时候我们就移动左窗口, 并将出窗口的每个字符次数减1,即S[s[i]]--;

然后每次更新窗口的最大长度, j - i + 1 为当前窗口的长度;
如果比更新前大, 则更新窗口的最大长度为j - i + 1;
否则不更新

【代码】

int lengthOfLongestSubstring(char * s){
    int len = strlen(s);
    if(len == 0)
        return 0;
    int S[256] = {0};
    int i, j, m = 0;
    for(i = 0, j = 0; j < len; j++){
        S[s[j]]++;
        while(S[s[j]] > 1){
            S[s[i]]--;
            i++;
        }
        m = fmax(m, j - i + 1);
    }
    return m;
}
int lengthOfLongestSubstring(char * s)
{
    //类似于hash的思想
    //滑动窗口维护
    int left = 0;
    int right = 0;
    int max = 0;
    int i,j;
    int len = strlen(s);
    int haveSameChar = 0;
    for(i =0; i < len ; i++  )
    {
        if(left <= right)
        {   
            //检测是否出现重复
             //循环遍历整个数组 left -> right
            haveSameChar = 0;
            for(j = left; j < right ; j++)
            {
                if(s[j] == s[right])
                {
                    haveSameChar = 1;
                    break;
                }
            }
            if(haveSameChar)
            {
                //指向下一个
                left = j +1;
            }
        }
        //统计最大的间距
        max = max < (right - left + 1) ? (right - left + 1): max;
        right++;
    }
    return max;
}

3.交错字符串

【题目】

【分析】

【代码】

bool isInterleave(char* s1, char* s2, char* s3) {
    int n = strlen(s1), m = strlen(s2), t = strlen(s3);

    int f[n + 1][m + 1];
    memset(f, 0, sizeof(f));

    if (n + m != t) {
        return false;
    }

    f[0][0] = true;
    for (int i = 0; i <= n; ++i) {
        for (int j = 0; j <= m; ++j) {
            int p = i + j - 1;
            if (i > 0) {
                //f[i][j] |= (f[i - 1][j] && s1[i - 1] == s3[p]);
                f[i][j] =(f[i-1][j]&&s1[i-1]==s3[p]);
            }
            if (j > 0) {
                f[i][j] |= (f[i][j - 1] && s2[j - 1] == s3[p]);
            }
        }
    }

    return f[n][m];
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值