leetcode1255. 得分最高的单词集合

该博客介绍了如何解决LeetCode上的1255题,即利用回溯法找出由给定字母组成的单词集合,以获得最高得分。玩家需从单词表中选择能用letters中字母拼写的单词,并且每个字母最多使用一次,最终目标是最大化所有单词的得分总和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     题目链接:力扣icon-default.png?t=L892https://leetcode-cn.com/problems/maximum-score-words-formed-by-letters/

题意:

你将会得到一份单词表 words,一个字母表 letters (可能会有重复字母),以及每个字母对应的得分情况表 score。

请你帮忙计算玩家在单词拼写游戏中所能获得的「最高得分」:能够由 letters 里的字母拼写出的 任意 属于 words 单词子集中,分数最高的单词集合的得分。

单词拼写游戏的规则概述如下:

玩家需要用字母表 letters 里的字母来拼写单词表 words 中的单词。
可以只使用字母表 letters 中的部分字母,但是每个字母最多被使用一次。
单词表 words 中每个单词只能计分(使用)一次。
根据字母得分情况表score,字母 'a', 'b', 'c', ... , 'z' 对应的得分分别为 score[0], score[1], ..., score[25]。
本场游戏的「得分」是指:玩家所拼写出的单词集合里包含的所有字母的得分之和。

方法: 回溯法

class Solution {
private:
    int size;
    const int SIZE = 27;
    vector<int> vct;//哈希表,用于记录小写字母出现的次数
    vector<int> tmp;
    vector<int> score;
    vector<string> words;//存储单词
    int maxS = 0;//最大的分
    void backTrack(int index,int s)//i表示第几个单词,s表示得分
    {
        for(int i=index+1;i<size;i++)
        {
            if(!isValid(words[i])) continue;//字符串里的字符凑不齐就跳过
            //凑齐了
            int s1 = s;
            vector<int> pre = tmp;
            for(int j=0;j<26;j++)
            {
                s1 +=  score[j]*tmp[j];//更新得分
                vct[j]-=tmp[j];//更新vct
            }
            maxS = max(maxS,s1);
            backTrack(i,s1);//回溯
            for(int j=0;j<26;j++)
            {
                vct[j]+=pre[j];//更新vct
            }
        }
    }
    bool isValid(string str)//判断字符串内的字符是否符合条件
    {
        tmp = vector<int>(SIZE,0);
        for(auto& ch:str)
        {
            tmp[ch-'a']++;
        }
        for(int i=0;i<26;i++)
        {
            if(tmp[i]>vct[i]) return false;
        }
        return true;
    }
public:
    int maxScoreWords(vector<string>& words, vector<char>& letters, vector<int>& score) {
        this->words = words;//将字符串集合变为全局
        this->score = score;
        vct = vector<int>(SIZE,0);
        for(int i=0;i<letters.size();i++)//更新哈希表
        {
            vct[letters[i]-'a']++;//对应的字母数量自加
        }
        size = words.size();//统计单词数目
        for(int i=0;i<size;i++)
        {
            if(!isValid(words[i])) continue;//字符串里的字符凑不齐就跳过
            int s = 0;//统计得分
            vector<int> pre = tmp;
            //凑齐了
            for(int j=0;j<26;j++)
            {
                s +=  score[j]*tmp[j];//更新得分
                vct[j]-=tmp[j];//更新vct
            }
            maxS = max(maxS,s);//更新最大得分
            backTrack(i,s);//回溯
            for(int j=0;j<26;j++)
            {
                vct[j]+=pre[j];//更新vct
            }
        }
        return maxS;//返回最大得分
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值