当前位置: 首页 > article >正文

【记忆回溯】【深度搜索】【动态规划】【字符串】【力扣】单词拆分

目录

题目描述

解题思路

解答(c语言)


题目描述

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true

注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

示例 1:

输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。

示例 2:

输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。
     注意,你可以重复使用字典中的单词。

示例 3:

输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false

解题思路

解题思路:深度遍历的思想

从字符串的起始位置开始匹配字典中的单词,如果能匹配到,则继续从字符串中该单词后面继续匹配字典中的单词,直到完全匹配。

  • 比如s = "catsandog",wordDict = {"cats","dog","sand","and","cat"}
  • index = 0时,对"catsandog"进行前缀匹配,可以匹配到"cats",也可以匹配到"cat"等,则需要记忆回溯,也就是深度遍历,先匹配到"cats"处理,然后更新index = 4
  • index = 4时,对"andog"进行前缀匹配,匹配到"and",然后更新index = 7
  • index = 7时,对"og"进行前缀匹配,没有一个能匹配,然后返回到index = 4时,寻找能否有匹配的单词,已经匹配过的不再匹配,比如"and"
    • 如果index = 4时没有可匹配的,返回index = 0时的前缀匹配,寻找能否有匹配的单词
    • 如果index = 4时有可匹配的,则继续向下匹配,像刚才那样
  • 就这样,来来回回寻找(深度遍历),直到index = strlen(s),说明可以s能被wordDict拼接。如果index从0到1,到2,到strlen(s) - 1对字典所有匹配都尝试完了,仍然没有则说明不能被拼接

注意点:已经匹配过的不再匹配,提交后才发现,否则会超时,因为会有很多重复判断

解答(c语言)

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

int isMatch = 0;  // 标记能否被分割

int Forward(int index, char* s, size_t sLen, char **wordDict, int wordDictSize, int *isHasJudge)
{
    // 一旦有拼接成功的方案,则不再找寻其它方案
    if (isMatch == 1) {
        return 1;
    }

    // 恰好拼接成功
    if (index == sLen) {
        isMatch = 1;
        return 1;
    }

    // 无法拼接成功
    if (index > sLen) {
        return -1;
    }

    // 判断过的不再判断
    if (isHasJudge[index] == 1) {
        return -1;
    }


    // 遍历全部单词判断
    for (int j = 0; j < wordDictSize; j++) {
        size_t len = strlen(wordDict[j]);
        if (strncmp(s + index, wordDict[j], len) == 0) {
            int ret = Forward(index + len, s, sLen, wordDict, wordDictSize, isHasJudge);
            if (ret == 1) {
                return 1;
            }
        }
    }

    // 已判断过的做好标记
    isHasJudge[index] = 1;

    // 如果没有一个单词能匹配,则返回负数
    return -1;
}

bool wordBreak(char* s, char **wordDict, int wordDictSize) 
{
    // 每个用例会更改全局变量,需要重新初始化
    isMatch = 0;  

    size_t sLen = strlen(s);

    // 记录每个下标(0,1,2,..., sLen-1)是否已经和所有子串匹配过
    int isHasJudge[sLen]; 
    memset(isHasJudge, 0, sizeof(isHasJudge));

    // 深度遍历寻找所有方案
    Forward(0, s, sLen, wordDict, wordDictSize, isHasJudge);

    return isMatch == 1;
}

int main() 
{
    int select = 3;
    if (select == 1) {
        char *s = "catsandog";
        char *wordDict[] = {"cats","dog","sand","and","cat"};
        wordBreak(s, wordDict, 5);
    } else if  (select == 2) {
        char *s = "applepenapple";
        char *wordDict[] = {"apple","pen"};
        wordBreak(s, wordDict, 2);
    } else if (select == 3) {
        char *s = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab";
        char *wordDict[] = {"a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"};
        wordBreak(s, wordDict, 10);
    }

    return 0;
}


end


http://www.kler.cn/a/284390.html

相关文章:

  • JavaSecLab靶场搭建
  • 图论-代码随想录刷题记录[JAVA]
  • 【机器学习】如何配置anaconda环境(无脑版)
  • docker配置代理解决不能拉镜像问题
  • 今日 AI 简报 | 开源 RAG 文本分块库、AI代理自动化软件开发框架、多模态统一生成框架、在线图像背景移除等
  • @ComponentScan:Spring Boot中的自动装配大师
  • Hive SQL 练习
  • 2024 年的 Web3 游戏:演变、趋势和市场动态
  • 【云游戏】点量云流赋能大型游戏新体验
  • MP条件构造器之常用功能详解(or、and、exists、notExists)
  • 【机器学习】9. softmax(Multinomial Logistic Regression)
  • SQL数据库教案(入门必备)
  • 【C++ 第十六章】哈希
  • C# 弹出USB移动存储设备【附源码】
  • 假如我是前端面试官
  • 解决移动端使用Vant van-overlay 遮罩层导致的弹窗不可滚动问题
  • Linux 非root用户部署elasticsearch 7.17.23和ik分词器
  • cnocr 安装
  • 华为云征文|Flexus云服务器搭建基础环境
  • 聚合函数的艺术:SQL中的SUM、AVG、MAX、MIN深度解析
  • JavaScript在网页设计
  • LuaJit分析(六)luajit -bl 命令分析
  • OpenCV几何图像变换(11)极坐标转换函数warpPolar()的使用
  • 微服务事务管理
  • 计网_整体概念逻辑简单过一遍
  • 谷粒商城实战笔记-265~268-商城业务-订单服务-订单确认页模型抽取和数据填充-Feign丢失数据问题