【每日一题Day130】LC1255得分最高的单词集合 | 回溯

简介: 【每日一题Day130】LC1255得分最高的单词集合 | 回溯

得分最高的单词集合【LC1255】

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

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

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

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

就是被困难题吓了一跳

  • 思路:
    回溯枚举每一种子集情况,如果字母表的字母可以组成该子集的多所有单词,那么记录并更新分数,最后返回最大值
  • 回溯三部曲
  • path(当前已经获得的分数),i(记录本层递归中,从哪个字符串开始遍历)
  • 全局变量:(存放符合条件单一结果),res(存放符合条件的单词子集的最大分数),words,score
  • 回溯函数终止条件
  • 当搜索到单词表的末尾时,更新结果并返回
  • 回溯搜索的遍历过程:分两种情况考虑
  • 不选择单词words[i],直接递归到下一个单词
  • 选择单词words[i],剩余字母表存量能够存放该单词时,才能搜索下一个单词,递归结束后需要回溯
class Solution {
    int res;
    int[] counts, score;
    String[] words;
    public int maxScoreWords(String[] words, char[] letters, int[] score) {
        this.score = score;
        this.words = words;
        res = 0;
        counts = new int[26];
        for (char letter : letters){
            counts[letter - 'a']++;
        }
        backtracking(0, 0);
        return res;
    }
    public void backtracking(int path, int i){
        if (i == words.length){
            res = Math.max(res, path);
            return;
        }
        // 不选words[i]
        backtracking(path, i + 1);
        // 选words[i]
        boolean flag = true;
        for (char c : words[i].toCharArray()){
            counts[c - 'a']--;
            path += score[c - 'a'];
            if (counts[c - 'a'] < 0){
                flag = false;
            }  
        }
        if (flag){
            backtracking(path, i + 1);
        }
        // 回溯
        for (char c : words[i].toCharArray()){
            counts[c - 'a']++;
        }
    }
}

image.png

目录
相关文章
|
4天前
【每日一题Day369】LC187重复的DNA序列 | 字符串哈希
【每日一题Day369】LC187重复的DNA序列 | 字符串哈希
27 1
|
4天前
【每日一题Day301】LC2337移动片段得到字符串 | 双指针 计分
【每日一题Day301】LC2337移动片段得到字符串 | 双指针 计分
26 0
|
4天前
【每日一题Day342】LC2578最小和分割 | 贪心
【每日一题Day342】LC2578最小和分割 | 贪心
21 0
|
4天前
【每日一题Day161】LC1641统计字典序元音字符串的数目 | 数位dp
【每日一题Day161】LC1641统计字典序元音字符串的数目 | 数位dp
28 0
|
4天前
【每日一题Day159】LC1638统计只差一个字符的子串数目 | 枚举
【每日一题Day159】LC1638统计只差一个字符的子串数目 | 枚举
20 0
|
4天前
【每日一题Day277】LC2569更新数组后处理求和查询 | 线段树
【每日一题Day277】LC2569更新数组后处理求和查询 | 线段树
15 0
|
4天前
【每日一题Day160】LC1092最短公共超序列 | 动态规划
【每日一题Day160】LC1092最短公共超序列 | 动态规划
22 0
【每日一题Day160】LC1092最短公共超序列 | 动态规划
|
4天前
|
存储
【每日一题Day307】LC56合并区间 | 排序
【每日一题Day307】LC56合并区间 | 排序
20 0
|
4天前
【每日一题Day233】LC1170比较字符串最小字母出现频次 | 前缀和
【每日一题Day233】LC1170比较字符串最小字母出现频次 | 前缀和
22 0
|
4天前
|
vr&ar
【每日一题Day166】LC1053交换一次的先前排列 | 贪心
【每日一题Day166】LC1053交换一次的先前排列 | 贪心
51 1