leetcode 字符串之单词

  • leetcode820. 单词的压缩编码
    • 1. 题目
    • 2. 解答
  • leetcode139. 单词拆分
    • 1. 题目
    • 2. 解答
  • leetcode127. 单词接龙
    • 1. 题目
    • 2. 解答
  • leetcode916. 单词子集
    • 1. 题目
    • 2. 解答
  • leetcode648. 单词替换
    • 1. 题目
    • 2. 解答

leetcode820. 单词的压缩编码

1. 题目

给定一个单词列表,我们将这个列表编码成一个索引字符串 S 与一个索引列表 A。
例如,如果这个列表是 [“time”, “me”, “bell”],我们就可以将其表示为 S = “time#bell#” 和 indexes = [0, 2, 5]。
对于每一个索引,我们可以通过从字符串 S 中索引的位置开始读取字符串,直到 “#” 结束,来恢复我们之前的单词列表。
那么成功对给定单词列表进行编码的最小字符串长度是多少呢?
示例:
输入: words = [“time”, “me”, “bell”]
输出: 10
说明: S = “time#bell#” , indexes = [0, 2, 5] 。

2. 解答

int Cmp(const void* a, const void* b)
{char* s1 = *(char**)a;char* s2 = *(char**)b;return strcmp(s1, s2);
}int minimumLengthEncoding(char ** words, int wordsSize){if (words == NULL || wordsSize == 0) {return 0;}int *size = (int *)calloc(wordsSize, sizeof(int));int totalLen = 0;for (int i = 0; i < wordsSize; i++) {int left = 0;int right = strlen(words[i]) - 1;while (left < right) {char tmp = words[i][left];words[i][left] = words[i][right];words[i][right] = tmp;left++;right--;}}qsort(words, wordsSize, sizeof(char*), Cmp);for (int i = 0; i < wordsSize; i++) {size[i] = strlen(words[i]);totalLen += size[i];}totalLen += wordsSize;for (int i = 0; i < wordsSize - 1; i++) {if (strncmp(words[i], words[i + 1], size[i]) == 0) {totalLen -= (size[i] + 1);}}free(size);return totalLen;
}

leetcode139. 单词拆分

1. 题目

给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。

说明:
拆分时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。

示例 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

2. 解答

#define MAXSIZE 10000bool wordBreak(char * s, char ** wordDict, int wordDictSize) {int queue[MAXSIZE] = { 0 };int head = 0, tail = 0;int i;char temp[MAXSIZE] = { 0 };int sLen = strlen(s);int vist[MAXSIZE] = { 0 };for (i = 0; i < wordDictSize; i++) {int len = strlen(wordDict[i]);strncpy(temp, s, len);temp[len] = '\0';if (strcmp(temp, wordDict[i]) == 0) {queue[tail++] = len;vist[len] = 1;}}char* current;while (head < tail) {int currentLen = queue[head];head++;current = s + currentLen;if (*current == '\0') {return true;}for (int j = 0; j < wordDictSize; j++) {int len = strlen(wordDict[j]);if (len > strlen(current)) {continue;}strncpy(temp, current, len);temp[len] = '\0';if (strcmp(temp, wordDict[j]) == 0) {if (vist[currentLen + len] == 1) {continue;}queue[tail++] = currentLen + len;vist[currentLen + len] = 1;}}}return false;
}

leetcode127. 单词接龙

1. 题目

给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:
每次转换只能改变一个字母。
转换过程中的中间单词必须是字典中的单词。

示例 1:
输入:
beginWord = “hit”,
endWord = “cog”,
wordList = [“hot”,“dot”,“dog”,“lot”,“log”,“cog”]
输出: 5
解释: 一个最短转换序列是 “hit” -> “hot” -> “dot” -> “dog” -> “cog”,
返回它的长度 5。

示例 2:
输入:
beginWord = “hit”
endWord = “cog”
wordList = [“hot”,“dot”,“dog”,“lot”,“log”]
输出: 0
解释: endWord “cog” 不在字典中,所以无法进行转换。

2. 解答

#define MAXSIZE 10000int isChange(char *s, char *t)
{int count = 0;for (int i = 0; i < strlen(s); i++) {if (s[i] != t[i]) {count++;}}if (count == 1) {return 1;} else {return 0;}
}int ladderLength(char * beginWord, char * endWord, char ** wordList, int wordListSize) {char *queue[MAXSIZE];for (int i = 0; i < wordListSize; i++) {if (strcmp(endWord, wordList[i]) == 0) {break;}if (i == wordListSize - 1) {return 0;}}int isVisted[MAXSIZE] = { 0 };int step = 1;int head = 0;int tail = 0;queue[tail++] = beginWord;while (head != tail) {int scop = tail - head;for (int i = 0; i < scop; i++) {char *temp = queue[head++];if (strcmp(temp, endWord) == 0) {return step;}for (int j = 0; j < wordListSize; j++) {if (isVisted[j] == 0 && isChange(temp, wordList[j])) {isVisted[j] = 1;queue[tail++] = wordList[j];}}}step++;}return 0;
}

leetcode916. 单词子集

1. 题目

我们给出两个单词数组 A和B。每个单词都是一串小写字母。
现在,如果b 中的每个字母都出现在 a 中,包括重复出现的字母,那么称单词 b 是单词 a 的子集。 例如,“wrr” 是 “warrior” 的子集,但不是 “world” 的子集。
如果对 B 中的每一个单词b,b 都是 a 的子集,那么我们称A 中的单词 a 是通用的。
你可以按任意顺序以列表形式返回A 中所有的通用单词。

示例 1:
输入:A = [“amazon”,“apple”,“facebook”,“google”,“leetcode”], B = [“e”,“o”]
输出:[“facebook”,“google”,“leetcode”]

示例 2:
输入:A = [“amazon”,“apple”,“facebook”,“google”,“leetcode”], B = [“l”,“e”]
输出:[“apple”,“google”,“leetcode”]

示例 3:
输入:A = [“amazon”,“apple”,“facebook”,“google”,“leetcode”], B = [“e”,“oo”]
输出:[“facebook”,“google”]

示例 4:
输入:A = [“amazon”,“apple”,“facebook”,“google”,“leetcode”], B = [“lo”,“eo”]
输出:[“google”,“leetcode”]

示例 5:
输入:A = [“amazon”,“apple”,“facebook”,“google”,“leetcode”], B = [“ec”,“oc”,“ceo”]
输出:[“facebook”,“leetcode”]

2. 解答

#define NUM 26
#define MAX(a, b) (((a) > (b)) ? (a) : (b))char ** wordSubsets(char ** A, int ASize, char ** B, int BSize, int* returnSize) {char **res = (char **)malloc(sizeof(char *) * ASize);*returnSize = 0;int numB[NUM] = { 0 };for (int i = 0; i < BSize; i++) {int alphaB[NUM] = { 0 };for (int j = 0; j < strlen(B[i]); j++) {alphaB[B[i][j] - 'a']++;}for (int k = 0; k < NUM; k++) {numB[k] = MAX(numB[k], alphaB[k]);}}for (int i = 0; i < ASize; i++) {int numA[NUM] = { 0 };int flag = 1;int len = strlen(A[i]);for (int j = 0; j < len; j++) {numA[A[i][j] - 'a']++;}for (int j = 0; j < NUM; j++) {if (numB[j] != 0 && numA[j] < numB[j]) {flag = 0;break;}}if (flag == 1) {res[*returnSize] = (char *)malloc(sizeof(char) * (len + 1));memcpy(res[*returnSize], A[i], len);res[*returnSize][len] = '\0';*returnSize += 1;}}return res;
}

leetcode648. 单词替换

1. 题目

在英语中,我们有一个叫做 词根(root)的概念,它可以跟着其他一些词组成另一个较长的单词——我们称这个词为 继承词(successor)。例如,词根an,跟随着单词 other(其他),可以形成新的单词 another(另一个)。

现在,给定一个由许多词根组成的词典和一个句子。你需要将句子中的所有继承词用词根替换掉。如果继承词有许多可以形成它的词根,则用最短的词根替换它。
你需要输出替换之后的句子。

示例 1:
输入:dictionary = [“cat”,“bat”,“rat”], sentence = “the cattle was rattled by the battery”
输出:“the cat was rat by the bat”

示例 2:
输入:dictionary = [“a”,“b”,“c”], sentence = “aadsfasf absbs bbab cadsfafs”
输出:“a a b c”

示例 3:
输入:dictionary = [“a”, “aa”, “aaa”, “aaaa”], sentence = “a aa a aaaa aaa aaa aaa aaaaaa bbb baba ababa”
输出:“a a a a a a a a bbb baba a”

示例 4:
输入:dictionary = [“catt”,“cat”,“bat”,“rat”], sentence = “the cattle was rattled by the battery”
输出:“the cat was rat by the bat”

示例 5:
输入:dictionary = [“ac”,“ab”], sentence = “it is abnormal that this solution is accepted”
输出:“it is ab that this solution is ac”

提示:
1 <= dictionary.length <= 1000
1 <= dictionary[i].length <= 100
dictionary[i] 仅由小写字母组成。
1 <= sentence.length <= 10^6
sentence 仅由小写字母和空格组成。
sentence 中单词的总量在范围 [1, 1000] 内。
sentence 中每个单词的长度在范围 [1, 1000] 内。
sentence 中单词之间由一个空格隔开。
sentence 没有前导或尾随空格。

2. 解答

// C 库函数 char *strtok(char *str, const char *delim) 分解字符串 str 为一组字符串,delim 为分隔符。
// 该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。
// C 库函数 char *strstr(const char *haystack, const char *needle) 在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 '\0'。
// 该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回 null。
char *GetRoot(char **dictionary, int dictionarySize, char *str)
{char *res = str;for (int i = 0; i < dictionarySize; i++) {// strstr这里表示在str中第一次出现dictionary[i]的地方,如果等于str并且长度小于原词,则证明是前缀。if (strstr(str, dictionary[i]) == str && strlen(res) > strlen(dictionary[i])) {res = dictionary[i];}}return res;
}char * replaceWords(char ** dictionary, int dictionarySize, char * sentence)
{char * res = (char *)malloc(sizeof(char) * (strlen(sentence) + 1));memset(res, 0, strlen(sentence) + 1);char *p = NULL;char *tmp = NULL;int curLen = 0;//以空格将字符串分隔开p = strtok(sentence, " ");tmp = GetRoot(dictionary, dictionarySize, p);memcpy(res, tmp, strlen(tmp));curLen += strlen(tmp);while (p != NULL) {p = strtok(NULL, " ");if (p != NULL) {tmp = GetRoot(dictionary, dictionarySize, p);//用sprintf拼接字符串sprintf(res + curLen, " %s", tmp);curLen += (strlen(tmp) + 1);}}return res;
}

leetcode 字符串之单词相关推荐

  1. LeetCode 字符串(简单题)

    答案摘抄自: https://leetcode-cn.com/tag/string/ 13. 罗马数字转整数 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V ...

  2. 统计一个字符串中单词的个数

    <程序设计基础-c语言>杨莉 刘鸿翔 ISBN-978-7-03-032903-5 p113 习题4 7.统计一个字符串中单词的个数.字符串中两个空格之间的非空格字符串可看做单词. #in ...

  3. 七十二、Python | Leetcode字符串系列(下篇)

    @Author:Runsen @Date:2020/7/3 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ...

  4. 七十一、Python | Leetcode字符串系列(上篇)

    @Author:Runsen @Date:2020/7/3 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ...

  5. python中字符串乘法_python leetcode 字符串相乘实例详解

    给定两个以字符串形式表示的非负整数 num1 和  num2 ,返回  num1 和  num2 的乘积,它们的乘积也表示为字符串形式. 示例 1: 输入: num1 = "2", ...

  6. LeetCode 244. 最短单词距离 II(哈希map+set二分查找)

    文章目录 1. 题目 2. 解题 2.1 暴力超时 2.2 哈希表+set二分查找 1. 题目 请设计一个类,使该类的构造函数能够接收一个单词列表. 然后再实现一个方法,该方法能够分别接收两个单词 w ...

  7. LeetCode 245. 最短单词距离 III

    文章目录 1. 题目 2. 解题 1. 题目 给定一个单词列表和两个单词 word1 和 word2,返回列表中这两个单词之间的最短距离. word1 和 word2 是有可能相同的,并且它们将分别表 ...

  8. LeetCode 243. 最短单词距离

    文章目录 1. 题目 2. 解题 1. 题目 给定一个单词列表和两个单词 word1 和 word2,返回列表中这两个单词之间的最短距离. 示例: 假设 words = ["practice ...

  9. 1.7 编程基础之字符串 27 单词翻转 4分 python

    """ 1.7 编程基础之字符串 27 单词翻转 4分 http://noi.openjudge.cn/ch0107/24/ https://blog.csdn.net/ ...

最新文章

  1. Docker学习(八)-----Docker安装mysql
  2. 008_Input输入框
  3. Python学习之路 拓展篇 Pychram的应用
  4. boost::core实现交换std::type_info
  5. 路径中斜杠/、点斜杠./、点点斜杠../的区别
  6. 是网关吗_什么是边缘控制器?就是IPC+PLC+网关吗?今天就拆开一个来看看
  7. sperling指标 matlab,sperling指标计算实验报告
  8. properties文件 , properties类, 的作用
  9. MySql中执行 GROUP BY 分组 遇到 1055错误
  10. Hadoop单机环境搭建整体流程
  11. 换了路由器电脑都连不上网了_换了新路由器电脑连不上网
  12. java clock计时_Java Clock类– java.time.Clock
  13. 有了它,让我在bug面前一点也不慌!
  14. 蚂蚁庄园 php源码,求一个基于Auto.js的蚂蚁庄园脚本
  15. C#实现Astar 算法以及导航系统
  16. 【模拟电路知识】运算放大器没有反馈电路——做电压比较器应用
  17. iOS面试题(多线程篇)
  18. 2020-03-12
  19. GDB调试总结和实例
  20. 代码读智识  笔墨知人心 1

热门文章

  1. 生成 HashCode 一致的字符串
  2. H5客户端获取Url参数的方法
  3. 微信公众号 h5微信充值功能
  4. Certificate Vending Machine – Amazon IoT 设备接入 Amazon IoT 平台解决方案
  5. 关闭睿频提升续航静音运行
  6. linux服务器配置与管理_你需要知道什么才能成为系统管理员? | Linux 中国
  7. 区块链与分布式数据库的区别
  8. 2022河南萌新联赛第(二)场
  9. Repeater的查询,添加,修改,删除
  10. 国仁网络资讯:微信视频号怎么变现赚钱;首先要了解平台的底层逻辑与算法原理。