力扣刷题之676.实现一个魔法字典

题干描述

设计一个使用单词列表进行初始化的数据结构,单词列表中的单词 互不相同 。 如果给出一个单词,请判定能否只将这个单词中一个字母换成另一个字母,使得所形成的新单词存在于你构建的字典中。

实现 MagicDictionary 类:

  • MagicDictionary() 初始化对象
  • void buildDict(String[] dictionary) 使用字符串数组 dictionary 设定该数据结构,dictionary 中的字符串互不相同
  • bool search(String searchWord) 给定一个字符串 searchWord ,判定能否只将字符串中 一个 字母换成另一个字母,使得所形成的新字符串能够与字典中的任一字符串匹配。如果可以,返回 true ;否则,返回 false 。

示例:

输入
["MagicDictionary", "buildDict", "search", "search", "search", "search"]
[[], [["hello", "leetcode"]], ["hello"], ["hhllo"], ["hell"], ["leetcoded"]]
输出
[null, null, false, true, false, false]

解释
MagicDictionary magicDictionary = new MagicDictionary();
magicDictionary.buildDict(["hello", "leetcode"]);
magicDictionary.search("hello"); // 返回 False
magicDictionary.search("hhllo"); // 将第二个 'h' 替换为 'e' 可以匹配 "hello" ,所以返回 True
magicDictionary.search("hell"); // 返回 False
magicDictionary.search("leetcoded"); // 返回 False

题干解析

问题概述

        我们需要设计一个数据结构Magictionary,他可以使用单词列表进行初始化。随后,当给定一个单词时,给数据结构需要判断能否通过将单词中的某个字母替换为另一个字母,从而形成一个在字典中存在的新单词。

解题思路

1.创建数据结构
  • 我们定义了一个Magictionary结构体,该结构体包含一个字符指针数组dictionary用于存储字典单词,以及一个整数size用于存储字典中的单词数量。
2.初始化Magictionary对象
  • 使用MagictionaryCreate()函数初始化Magictionary对象。该函数分配内存并将dictionary初始化为NULL,size初始化为0。
3.构建字典
  • 使用magicDictionaryBuildDict()函数,该函数接受一个字符串数组dictionary和数组大小dictionarySize,并将其存储在MagicDictionary对象中。
  • 在这个函数中,我们为每个单词动态分配内存,并复制到MagicDictionary的dictionary字段中。
4.搜索单词
  • 使用magicDictionarySearch()函数,该函数接受一个待搜索的单词searchWord,并检查是否能够通过改变其中的一个字母,得到字典中已有的单词。
  • 搜索过程中,我们之一比较字典中的每个单词与searchWord,如果两个单词长度不同,直接跳过。
  • 对长度相同的单词,逐字符比较,统计不同字符的数量。如果不同字符恰好为1,则返回true,否则继续检查下一个单词。
5.释放内存
  • 最后,我们使用magicDictionaryFree()函数释放所有动态分配的内存,避免内存泄露。

详细代码如下 

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

//定义该字典的结构体
typedef struct {
	char** dictionary;//指向字典单词的字符指针数组
	int size;//当前字典中的单词数量
}MagicDictionary;

//初始化字典对象
MagicDictionary* magicDictionaryCreate() {
	MagicDictionary* obj = (MagicDictionary*)malloc(sizeof(MagicDictionary));//为字典对象动态分配内存
	obj->dictionary = NULL;//初始化为空
	obj->size = 0;//初始大小为0
	return obj;
}
//使用字典列表构建数据结构
void magicDictionaryBuildDict(MagicDictionary* obj, char** dictionary, int dictionarySize) {
	obj->dictionary = (char**)malloc(dictionarySize * sizeof(char*));//动态分配内存空间
	for (int i = 0; i < dictionarySize; ++i)
	{
		obj->dictionary[i] = (char*)malloc((strlen(dictionary[i]) + 1) * sizeof(char));
		strcpy(obj->dictionary[i], dictionary[i]);//拷贝字典单词
	}
}

//定义一个函数用于搜索单词,判断是否可以通过替换一个字母得到字典中的单词
bool magicDictionarySearch(MagicDictionary* obj, char* searchWord) {
	for (int i = 0; i < obj->size; ++i)
	{
		char* dictWord = obj->dictionary[i];
		int len = strlen(dictWord);
		if (len != strlen(searchWord))
		{
			continue;//如果长度不同,跳过检查
		}
		int diffCount = 0;//不同字符的计数
		for (int j = 0; j < len; j++)
		{
			if (searchWord[j] != dictWord[j]) {
				diffCount++;//增加不同字符的计数
				if (diffCount > 1)
				{
					break;//如果不超过一个字符停止检查
				}
			}
		}
		if (diffCount == 1)
		{
			return true;//如果恰好有一个字符不同,返回true
		}
	}
	return false;//如果没有符合条件的单词,返回false
}
//释放MagicDictionary对象
void magicDictionaryFree(MagicDictionary* obj) {
	for (int i = 0; i < obj->size; ++i)
	{
		free(obj->dictionary[i]);//释放每个单词的内存
	}
	free(obj->dictionary);//释放字典数组的内存
	free(obj);//释放MagicDictionary对象
}
// 示例使用
int main() {
	// 创建MagicDictionary对象
	MagicDictionary* obj = magicDictionaryCreate();

	// 构建字典
	char* dictionary[] = { "hello", "leetcode", "magic" };
	int dictionarySize = sizeof(dictionary) / sizeof(dictionary[0]);
	magicDictionaryBuildDict(obj, dictionary, dictionarySize);

	// 搜索单词
	char* searchWord1 = "hhllo";
	bool result1 = magicDictionarySearch(obj, searchWord1);
	printf("搜索'%s': %s\n", searchWord1, result1 ? "true" : "false");

	char* searchWord2 = "leetcoded";
	bool result2 = magicDictionarySearch(obj, searchWord2);
	printf("搜索'%s': %s\n", searchWord2, result2 ? "true" : "false");

	// 释放MagicDictionary对象
	magicDictionaryFree(obj);

	return 0;
}

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值