【算法】得分最高的单词集合Leetcode.1255

题目

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

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

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

  • 玩家需要用字母表 letters 里的字母来拼写单词表 words 中的单词。

  • 可以只使用字母表 letters 中的部分字母,但是每个字母最多被使用一次。

  • 单词表 words 中每个单词只能计分(使用)一次。

  • 根据字母得分情况表score,字母 ‘a’, ‘b’, ‘c’, … , ‘z’ 对应的得分分别为 score[0], score[1], …, score[25]。

  • 本场游戏的「得分」是指:玩家所拼写出的单词集合里包含的所有字母的得分之和。

思路

  1. 遍历字母表 letters,统计每个字符出现的次数。
  2. 遍历单词表 words,统计每个单词的得分。
  3. 对于每个单词,判断字母表 letters 中是否包含单词中的每个字符,如果包含则继续判断字母表 letters
    中每个字符的数量是否大于等于单词中该字符的数量。
  4. 如果字母表 letters 中包含单词中的所有字符并且每个字符的数量都不小于单词中该字符的数量,则计算该单词的得分。
  5. 在所有满足条件的单词中找到得分最高的一个,返回该得分。

解题代码

class Solution {
    
    public int max;

    public int maxScoreWords(String[] words, char[] letters, int[] score) {
        int[] lettersCnt = new int[26];
        for(int i = 0; i < letters.length; i++){
            lettersCnt[letters[i] - 'a'] ++;
        }
        int[] wordsScore = new int[words.length];
        for(int i = 0; i < words.length; i++){
            int sum = 0;
            for(int j = 0; j < words[i].length(); j++ ){
                char c = words[i].charAt(j);
                sum += score[c - 'a'];
            }
            wordsScore[i] = sum;
        }
        dfs(lettersCnt, wordsScore, words, 0, 0);
        return max;
    }
    public void dfs(int[] lettersCnt, int[] wordsScore,String[] words, int index,int res ){
        for(int i = index; i < words.length ; i++){
            //从字母表删除对应字母数目,如果有小于0 的不成立
            if(check(lettersCnt, words[i], -1)){
                dfs(lettersCnt, wordsScore, words, i + 1, res + wordsScore[i]);
            }
            //回溯,从字母表加回去
            check(lettersCnt, words[i], 1);
        }
        max = Math.max(max, res);
    }

    public boolean check(int[] lettersCnt, String words, int m){
        boolean flag = true;
        for(int i = 0 ; i < words.length(); i ++){
            lettersCnt[words.charAt(i) - 'a'] += m;
            if(lettersCnt[words.charAt(i) - 'a'] < 0){
                flag = false;
            }
        }
        return flag;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值