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. jQuery1·3中文参考文档下载
  2. Hibernate4继承映射
  3. Boost.Flyweight 复合设计示例
  4. python fpga_如何实现用Python开发FPGA?
  5. vue_prop单向数据流
  6. 网站程序数据库怎么上传到服务器上,网站的数据库怎么上传到服务器
  7. 电脑c语言怎么调出来的,c语言系统源代码_C语言判断系统版本的代码怎样将值调出来啊...
  8. 架构设计 —— 性能选型、高可用
  9. error 1044 (42000):access denied for user ''@'localhost' to database 'mysql'
  10. DIV_ROUND_CLOSEST函数
  11. android导航工厂设置密码,导航工厂设置密码大全,所有导航工厂密码多少
  12. VBA中byref类型不匹配 ByRef Argument Type Mismatch错误
  13. Arcpy基础入门-4、arcpy工具进阶
  14. Java集合面试题汇总【附答案】持续更新
  15. 金蝶K3案例教程采购管理后台配置
  16. 如何把大量动图一键压缩到微信可用的大小?
  17. 点击应用图标-应用(Activity)的启动流程
  18. 出门问问CEO李志飞:巨头失控打架时 我们就修炼内功
  19. java wifi定位原理_基于wifi的室内定位方法深度分析.doc
  20. 1.3 应用视觉设计

热门文章

  1. 如何设置使Windows XP实现自动登录
  2. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(4)- Flashloader初体验(blhost)...
  3. LeetCode912. 排序数组(JavaScript手撕各种排序算法)
  4. 如何用C语言来实现【三子棋游戏】
  5. ONE一言每天一句名言API
  6. 全智通A+常见问题汇总解答—A+新维修单登记保存后会把原来的车辆信息中的商业险保险险种的内容清除。
  7. CSS--margin塌陷问题
  8. Redis 知识点和面试题(持续更新ing)
  9. 辛酸,面试蚂蚁Offer的经验都在这里了!
  10. jq jqprint 设置页脚_jquery web打印 取消 页眉和页脚