[算法积累] [leetcode] [查找后缀/前缀] [5] 820. 单词的压缩编码

本文探讨了三种编码优化策略:暴力法、字典树和排序法,旨在通过实例讲解如何有效减少字符串编码的总长度。首先介绍了暴力法的基本思想,即利用集合存储并逐个检查子串;随后深入解析了字典树的构建和插入过程,展示了其在处理字符串集合时的优势;最后,提出了基于字符串反转和排序的高效算法,通过避免重复子串进一步压缩编码空间。文章还附带了详细的代码实现和学习心得。

0.前言

写了整整一个上午,从8点50到11点半。我果然还是太菜了。继续加油吧!!
写在这里,方便回顾。

1.思路

本题共有三种思路.

1.1暴力

使用set存储所有的字符串。
之后遍历每个字符串的子串,如果其在set中存在,则将其移除。

	unordered_set<string> list(words.begin(),words.end());
	for(auto item:list){
		for(int i = 1;i<item.size();i++){
			list.erase(item.substr(i));
	 	}
	}
	int res = 0;
	for(auto item:list){
	 res += item.size()+1;
	}
	return res;
	

1.2 字典树

两个对象,一个TireNode,是一个26个对象的数组。一个TireTree主要保存根节点。

class TireNode{
    public:TireNode* arr[26];
};

class TireTree{
    TireNode* root = new TireNode();
public:
	//从后开始遍历
    int insert(string str){
        TireNode* cur = root;
        bool isNew = false;
        for(int i = str.size()-1;i>=0;i--){
            int c = str[i]-'a';
            if(cur->arr[c] == NULL){
                cur->arr[c] = new TireNode();
                isNew = true;
            }
            cur = cur->arr[c];
        }
        return isNew?str.size()+1 : 0;
    }
};

class Solution {
public:
    static bool cmp(string a,string b){
        return a.size() > b.size();
    }
    int minimumLengthEncoding(vector<string>& words) {
        //第二种方式,使用字典树
        int res = 0;
        TireTree* tree = new TireTree();
        sort(words.begin(),words.end(),cmp);
        for(auto item:words){
            res += tree->insert(item);
        }
        return res;

    }
};

1.3 排序

对每个字符串进行反转,之后进行排序。
如果发现前一个是后一个的子串,就不对其进行操作。否则统计长度。
要加上最后一个的长度

class Solution {
public:
    
    int minimumLengthEncoding(vector<string>& words) {
       int size = words.size();
       int res = 0;
       for(int i = 0;i<size;i++){
           reverse(words[i].begin(),words[i].end());
       }

       sort(words.begin(),words.end());

       for(int i = 0;i<words.size()-1;i++){
           if(words[i+1].find(words[i]) == 0){
               continue;
           }else{
               res += words[i].size()+1;
           }
       }
       res += (words[size-1].size()+1);

       return res;

    }
};

2.所学

2.1find_last_of/find_first_of

返回查找的第一个目标对象的尾字符/首字符下标.
如果当前字符串比所查字符串短,则返回当前字符串最后的下标

string a = "time";
string b = "me";
a.find_last_of(b)  //3
b.find_last_of(a) //1

2.2 reverse()

可以对数据进行交换,并且修改原数组

3.借鉴文章

其实大多都是看着题解改的,如有侵权,立马删除.
官方
tire树
反转

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值