8.15 哈希表中等 139 Word Break review 467 Unique Substrings in Wraparound String

139 Word Break【逐一对比vs.多种 分割 组合】


片面思考的思路:

cpp 复制代码
class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        //字符串和对应的字典,如果s种可以用空格分隔出一个或多个字典里的词就返回true
        //核心:按照字典里的词对s断句,对s遍历,如何判断s种有多余的字母是字典中不包含的?
        //细节:字典里的词会被多次使用,且不按顺序出
        //在这道题中,哈希表是怎么使用的?是存储字典中出现的单词个数?还是存储s中的单词出现的位置?
        //如何确定单词范围?对dic也是一个一个比较吗?比较后怎么锁定s中的位置?
        //单词范围由wordDic[i].size()确定,通过substr(pos,len)确定子串中的位置,哈希表用于存储开始位置和单词长度
        //是哪个循环套哪个循环?
        //因为一个字典会在s中多次出现且s的长度最大值才300所以Dic中嵌套s
        //如何让s遍历的时候跳过已经判断出的范围?或者说如何判定s没有被排除完?
        //s.replace(pos,len,'0')那这样就不需要哈希表了啊,直接最后遍历一遍是否全为0就好了
        //unordered_map<int,int> StartAndLength;
        int index = 0;
        for(int i = 0 ; i < wordDict.size();i++){
            int len = wordDict[i].size();
            int index = 0;//每次都从头开始遍历
            while(index < s.size()){
                if(s[index] == wordDict[i][0] && s.substr(index,len) == wordDict[i]){
                    //StartAndLength[index] = len;
                    s.replace(index,len,string(len,' '));
                    index+=len;
                }else{
                    index++;
                }
            }
        }
        for(char ch : s){
            if(ch != ' '){
                return false;
            }
        }
        return true;
    }
};

分析思路过程:

按照字典里的词对s断句,对s遍历,如何判断s种有多余的字母是字典中不包含的?

细节:字典里的词会被多次使用,且不按顺序出

在这道题中,哈希表是怎么使用的? 是存储字典中出现的单词个数?还是存储s中的单词出现的位置?-----》都是对中间态的记录,没有考虑哈希表的快速查找
如何确定单词范围? 对dic也是一个一个比较吗?比较后怎么锁定s中的位置?

单词范围由wordDic[i].size()确定,通过substr(pos,len)确定子串中的位置,哈希表用于存储开始位置和单词长度-------》没有考虑多种组合的情况
//是哪个循环套哪个循环?
//因为一个字典会在s中多次出现且s的长度最大值才300所以Dic中嵌套s

如何让s遍历的时候跳过已经判断出的范围?或者说如何判定s没有被排除完?

完全遍历一遍,所以主体还是对s的遍历

重新思考这道题目

按照难度来说,中等题也不太可能使用逐一对比+替换就能解决这个问题;

按照题型来说,这道题肯定需要用哈希表来解决

重新思考这道题,复盘哪些问题需要继续去思考的:

  • 在这道题中,哈希表是怎么使用的?
  • 如何确定单词范围?
  • 如何判断s中有多余的字母是字典中不包含的?---->这个是多种组合?

第一个问题: 哈希表可以完成字典的快速查找 unordered_set,记录中间状态 unordered_map;

如果是前一种,也就是将wordDict变了一下,用于快速查找s子串种是否是字典中的单词hash.find(s.substr(pos,len)) != hash.end()就是查到了,这段子串是存在于hash中的。

【这种方式特别适合需要频繁查找字典的情况,因为 unordered_set 的查找操作具有平均 O(1) 的时间复杂度,非常高效。】

后一种的话,就是用哈希表记录检查过的字符串段,用于判断s已经被分割的字段,但这个不适合多种组合 的情况,类似于逐一对比,认准一个死理不改变,所以还是使用字典的快速查找。
第二个问题: 单词范围一种是遍历,确定s中的开始位置使用while和Dict中的单词逐一对比,已经被pass了;另一种是动态规划,动态规划尤其适用于需要检查多个可能分割点并且组合的情况,如字符串分割、路径问题等。
第三个问题: 实际上是回答怎么判定s是否可以被Dict中的单词们分割,结合第二个问题,使用动态规划划分单词范围,其中的dp[i]数组表示的是s中前i个字符是否可以被完全分割,如果在最终的dp数组中s.size()位置标记为false则表示无法分割。

cpp 复制代码
class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        //动态规划
        //要做的事情是确定s中前i位是否可以被分割 dp[i]
        vector<bool> dp(s.size()+1,false);
        unordered_set<string> wordSet(wordDict.begin() , wordDict.end());
        //初始条件dp[0] = true;
        dp[0] = true;
        //遍历string s找合适的切割组合
        for(int i = 1 ; i <= s.size() ; i++){
            //判定是否可以被分割
            for(int j = 0 ; j < i ; j++){
                //判定条件,关系式:wordSet.find(s.substr(j , i-j)) != wordSet.end()
                if(dp[j] && wordSet.find(s.substr(j , i-j)) != wordSet.end()){
                    //可以被分割
                    dp[i] = true;
                    break;
                }
            }
        }
        return dp[s.size()];
    }
};

review 467 Unique Substrings in Wraparound String

cpp 复制代码
class Solution {
public:
    int findSubstringInWraproundString(string s) {
        //不同的非空的子串数目 不同+非空怎么判定-->记录数组dp 仅记录以26字母为结尾的
        //要找的是 且是不同的 存在于base中的子串 所以判定dp[i]为以i = ch - 'a'为索引,以ch为结尾的最长子串
        vector<int> dp(26,0);
        int maxLen = 0;
        //base的判定前者-后者为1 或者前者为z后者为a,记录长度
        for(int i = 0 ; i < s.size() ; i++){
            char ch = s[i];
            if(i>0 && (s[i] - s[i-1] == 1 || (s[i-1] == 'z' && s[i] == 'a'))){
                maxLen++;
            }else{
               //初始条件
               maxLen = 1;
            }
            dp[ch-'a'] = std::max(maxLen,dp[ch-'a']);
        }
        int ans = 0;
        for(int len : dp){
            ans += len;
        }
        return ans;
    }
};
相关推荐
Dong雨3 小时前
六大排序算法:插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序
数据结构·算法·排序算法
茶猫_3 小时前
力扣面试题 39 - 三步问题 C语言解法
c语言·数据结构·算法·leetcode·职场和发展
初学者丶一起加油3 小时前
C语言基础:指针(数组指针与指针数组)
linux·c语言·开发语言·数据结构·c++·算法·visual studio
半盏茶香5 小时前
C语言勘破之路-最终篇 —— 预处理(上)
c语言·开发语言·数据结构·c++·算法
2401_858286115 小时前
118.【C语言】数据结构之排序(堆排序和冒泡排序)
c语言·数据结构·算法
没事就去码5 小时前
RBTree(红黑树)
数据结构·c++
就爱学编程5 小时前
重生之我在异世界学编程之数据结构与算法:单链表篇
数据结构·算法·链表
CSCN新手听安11 小时前
list的常用操作
数据结构·list
梅茜Mercy13 小时前
数据结构:链表(经典算法例题)详解
数据结构·链表
青春男大13 小时前
java栈--数据结构
java·开发语言·数据结构·学习·eclipse