首页 > 其他分享 >1255. 得分最高的单词集合

1255. 得分最高的单词集合

时间:2023-04-08 18:23:23浏览次数:50  
标签:得分 cnt word score idx 单词 1255 words

题目链接:1255. 得分最高的单词集合

方法:暴力回溯

解题思路

观察可以发现,本题的数据量范围较小,使用暴力回溯不超过\(2^1\)\(^4\)次,需要注意的有,当选择一个单词时,必须保证当前提供的字符集合中剩余字符能够组成该单词\(check()\),选择以后将字符集合中对应字符数量减少\(destroy()\),回溯回来之后将其恢复\(resume()\)。

做题过程中的问题

  • 当想使用记忆化搜索进行优化时,发现由于选择当前单词时需要进行判定,并减小字符集合中的字符数量,会导致 \(cache\) 数组的更新不准确;因为子问题与当前问题两者之间不是独立关系,子问题的选取会影响当前单词是否能选。
  • 不要在开始对 \(words\) 数组中的单词分数进行预处理,因为 \(words\) 中出现的单词可以重复,那么可能最终求得分数是重复单词分数之和。

代码

class Solution {
public:
    unordered_map<char, int> cnt; // 统计letters中字符出现的数量
    bool check(string word) { // 检查单词word是否能被组成
        unordered_map<char, int> temp_cnt;
        for (auto &c : word) temp_cnt[c] ++ ;
        for (auto &i : temp_cnt) {
            if (cnt[i.first] < i.second) return false;
        }
        return true;
    }
    void destroy(string word) { // 当选择某个word时,要减小对应字母的数量
        for (auto &c : word) cnt[c] -- ;
    }
    void resume(string word) { // 回溯时,恢复现场
        for (auto &c : word) cnt[c] ++ ;
    }
    int dfs(vector<string>& words, vector<int>& score, int idx) {
        if (idx < 0) return 0;
        int temp1 = 0;
        if (check(words[idx])) { // 选择当前word
            destroy(words[idx]);
            int wordScore = 0; // 计算当前word的得分
            for (auto &c : words[idx]) wordScore += score[c - 'a'];
            temp1 = dfs(words, score, idx - 1) + wordScore;
            resume(words[idx]);
        }
        return max(temp1, dfs(words, score, idx - 1)); // 在选择当前word 和 不选择两种情况中取最大值
    }
    int maxScoreWords(vector<string>& words, vector<char>& letters, vector<int>& score) {
        for (auto &c : letters) cnt[c] ++ ;
        return dfs(words, score, words.size() - 1);
    }
};

复杂度分析

时间复杂度:\(O(m + L * 2^n)\),\(m\) 为 \(letters\) 数组长度,\(L\) 为 \(words[i]\) 的长度,\(n\) 为 \(words\) 数组长度;
空间复杂度:\(O(\Sigma)\),\(\Sigma\)为所有字符集合的大小,本题限定为小写字母,故\(\Sigma = 26\)

标签:得分,cnt,word,score,idx,单词,1255,words
From: https://www.cnblogs.com/lxycoding/p/17298949.html

相关文章

  • 洛谷P1308统计单词数,strtok函数的使用以及对于单词分割的一些思考
    [NOIP2011普及组]统计单词数题目描述一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意......
  • 12、单词
    2023/4/7SectionsAbudget,价格低廉的、花钱少的、预算、把······编入预算airline,航空公司budgetairline,廉价航空公司integrate,(使)融入、结合在一起cabin,机舱、船舱、小屋、小棚屋coincidence,巧合、巧事、并存psychology,心理学、心理associated,有联系的、有关......
  • 861. 翻转矩阵后的得分
    题目描述给了一个二维矩阵,矩阵的元素不是0就是1你可以进行任意次操作,让某行或者某列进行翻转元素的得分是每一行二进制的和问怎么操作可以让总得分最大?f1贪心+计算增量基本分析为啥可以贪心?(1)对每行来说,首位肯定是1最好,遮掩某些行需要翻转,某些不翻;(2)对同一列来说,大家的优先......
  • 蓝桥-单词分析
    https://www.lanqiao.cn/problems/504/learning/?page=1&first_category_id=1&sort=students_count&second_category_id=3#include<bits/stdc++.h>//包含所有常用的头文件usingnamespacestd;intmain(){map<char,int>m;//定义一个map,用于存储字符和出现次数的......
  • [每天例题]蓝桥杯 C语言 单词分析
    蓝桥杯C语言单词分析题目  题目要求1.寻找出现最多的字母和这个字母出现的次数。2.如果有多个字母出现的次数相等,输出字典序最小的那个。思路分析输入方法:方法一:1.可以通过数组来记录该单词,并为单词出现的每一个字母做上标记。2.可以采用for循环将字符串依次输......
  • 英语背单词 专四词汇 202304 ChatGPT
    英语背单词专四词汇202302以及202303ChatGPT-ChuckLu-博客园(cnblogs.com)2023-04-01Explainthemeaningofthefollowingwordsalongwithindexandphoneticsymbol:crusade,scandal,jack,peril,optimism,anchor,burial,jerk,erase,bother,sardine,album......
  • 华为OD机试 翻转单词顺序
    本期题目:翻转单词顺序题目输入一个英文文章片段翻转指定区间的单词顺序,标点符号和普通字母一样处理例如输入字符串 Iamadeveloper. 区间[0,3]则输出 developer.aamI输入使用换行隔开三个参数第一个参数为英文文章内容即英文字符串第二个参数为反转起始单词下标,下......
  • day8| 344.反转字符串;541.反转字符串II;剑指offer 05.替换空格;151.翻转字符串里的单词
    344.反转字符串 题目简述:编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组s的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组,使用O(1)的额外空间解决这一问题。 解题思路:没什么好说的,直接双指针 代码如下:classSolution:de......
  • 背单词
    ᅟᅠ       ‌‍‎‏ᅟᅠ       ‌‍‎‏ᅟᅠ       ‌‍‎‏ᅟᅠ       ‌‍‎‏ᅟᅠ       ‌‍‎‏ᅟᅠ       ......
  • 英语单词背诵
    问题以前花费大量时间记一个单词,时间过了,单词没住,一个小时大概40词左右,但是一到中午基本上忘完了,时间浪费,单词没记住,效率为零,个人也翻阅了前人的经验,英语单词学习,不是在......