字符串专题

1、同构字符串

给定两个字符串 s 和 t,判断它们是否是同构的。
如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。
所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。
示例 1:
输入: s = “egg”, t = “add”
输出: true
示例 2:
输入: s = “foo”, t = “bar”
输出: false
示例 3:
输入: s = “paper”, t = “title”
输出: true
 

class Solution {
public:

	//功能:判断两个字符串是不是同构字符串
	//入参:字符串s和t
	//返回:true表示同构,false表示不同构
	bool isPattern(string s, string t)
	{
		int len_s = s.length();
		int len_t = t.length();

		//若长度不同,肯定不同构
		if (len_s != len_t)
		{
			return false;
		}

		map<char, char> map_s;
		map<char, char> map_t;

		//建立s->t的映射关系
		for (int i = 0; i < len_s; i++)
		{
			if (map_s.find(s[i]) != map_s.end())  //判断map_s里是否为空
			{
				if (map_s[s[i]] != t[i])//不为空,表示有相同字符串,此处判断映射是否相同
				{
					return false;
				}
			}
			else
			{
				//map_s为空,建立映射关系
				map_s[s[i]] = t[i];
			}
		}

		//同理,建立t->s的映射关系
		for (int i = 0; i < len_s; i++)
		{
			if (map_t.find(t[i]) != map_t.end())  //判断map_t里是否为空
			{
				if (map_t[t[i]] != s[i])//不为空,表示有相同字符串,此处判断映射是否相同
				{
					return false;
				}
			}
			else
			{
				//map_s为空,建立映射关系
				map_t[t[i]] = s[i];
			}
		}

		return true;

	}

	vector<string> findAndReplacePattern(vector<string>& words, string pattern) 
	{
		vector<string> ans;

		for (int i = 0; i < words.size(); i++)
		{
			if (isPattern(words[i], pattern))
			{
				ans.push_back(words[i]);
			}
		}

		return ans;

	}
};

2、字母异位词分类

给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

示例:

输入: 
["eat", "tea", "tan", "ate", "nat", "bat"]
,
输出:
[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]
说明:

所有输入均为小写字母。
不考虑答案输出的顺序。
 

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        vector<vector<string>> res;
        map<string, vector<string>> mp;
        string temp;
        
        if (strs.empty())
        {
            return res;
        }
        for (int i = 0; i < strs.size(); i++)
        {
            temp = strs[i];
            sort(temp.begin(), temp.end());//排序之后,同词异位就变成相同了
            
            mp[temp].push_back(strs[i]); //同一类放到一个数组中
        }
        
        for (map<string, vector<string>>::iterator it = mp.begin(); it != mp.end(); it++)
        {
            res.push_back(it->second);
        }
        
        return res;
     
    }
};

3、在系统中查找重复文件

给定一个目录信息列表,包括目录路径,以及该目录中的所有包含内容的文件,您需要找到文件系统中的所有重复文件组的路径。一组重复的文件至少包括二个具有完全相同内容的文件。

输入列表中的单个目录信息字符串的格式如下:

"root/d1/d2/.../dm f1.txt(f1_content) f2.txt(f2_content) ... fn.txt(fn_content)"

这意味着有 n 个文件(f1.txt, f2.txt ... fn.txt 的内容分别是 f1_content, f2_content ... fn_content)在目录 root/d1/d2/.../dm 下。注意:n>=1 且 m>=0。如果 m=0,则表示该目录是根目录。

该输出是重复文件路径组的列表。对于每个组,它包含具有相同内容的文件的所有文件路径。文件路径是具有下列格式的字符串:

"directory_path/file_name.txt"

示例 1:

输入:
["root/a 1.txt(abcd) 2.txt(efgh)", "root/c 3.txt(abcd)", "root/c/d 4.txt(efgh)", "root 4.txt(efgh)"]
输出:  
[["root/a/2.txt","root/c/d/4.txt","root/4.txt"],["root/a/1.txt","root/c/3.txt"]]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-duplicate-file-in-system
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
public:
    vector<vector<string>> findDuplicate(vector<string>& paths) {
        string content;
        string prefix_path;
        string filename;
        vector<vector<string>> res;
        
        if (paths.empty())
        {
            return res;
        }
        
        map<string, vector<string>> mp;
        
        for (int i = 0; i < paths.size(); i++)
        {
            int index = 0;
            prefix_path.clear();
            while (index < paths[i].size() && paths[i][index] != ' ')
            {
                prefix_path += paths[i][index++];
            }
            prefix_path += "/";  //获取文件目录
            
            index++;  //跳过空格
            
            while (index < paths[i].size())
            {
                content.clear();
                filename.clear();
                                     
                while (index < paths[i].size() && paths[i][index] != '(')
                {
                    filename += paths[i][index++];
                }
                index++;//跳过“(”
                
                 while (index < paths[i].size() && paths[i][index] != ')')
                {
                    content += paths[i][index++];
                }
                
                index += 2;//跳过“)”和空格
                mp[content].push_back(prefix_path + filename);
            }   
           
        }
        
        for (auto it = mp.begin(); it != mp.end(); it++)
        {
            if (it->second.size() > 1) //判断是否有相同内容的文件路径,若没有则返回空
            {
                 res.push_back(it->second);
            }
           
        }
        
        return res;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值