leetcode
leetcode 2251 ~ 2300
找到最大开销的子字符串

找到最大开销的子字符串

难度:

标签:

题目描述

You are given a string s, a string chars of distinct characters and an integer array vals of the same length as chars.

The cost of the substring is the sum of the values of each character in the substring. The cost of an empty string is considered 0.

The value of the character is defined in the following way:

  • If the character is not in the string chars, then its value is its corresponding position (1-indexed) in the alphabet.
    • For example, the value of 'a' is 1, the value of 'b' is 2, and so on. The value of 'z' is 26.
  • Otherwise, assuming i is the index where the character occurs in the string chars, then its value is vals[i].

Return the maximum cost among all substrings of the string s.

 

Example 1:

Input: s = "adaa", chars = "d", vals = [-1000]
Output: 2
Explanation: The value of the characters "a" and "d" is 1 and -1000 respectively.
The substring with the maximum cost is "aa" and its cost is 1 + 1 = 2.
It can be proven that 2 is the maximum cost.

Example 2:

Input: s = "abc", chars = "abc", vals = [-1,-1,-1]
Output: 0
Explanation: The value of the characters "a", "b" and "c" is -1, -1, and -1 respectively.
The substring with the maximum cost is the empty substring "" and its cost is 0.
It can be proven that 0 is the maximum cost.

 

Constraints:

  • 1 <= s.length <= 105
  • s consist of lowercase English letters.
  • 1 <= chars.length <= 26
  • chars consist of distinct lowercase English letters.
  • vals.length == chars.length
  • -1000 <= vals[i] <= 1000

代码结果

运行时间: 81 ms, 内存: 16.5 MB


/*
 * 思路:
 * 1. 创建一个哈希映射,用于存储 chars 中字符对应的 vals 值。
 * 2. 使用流操作遍历字符串 s,对于每个字符,获取其对应的价值(在哈希映射中或通过其字母表位置计算)。
 * 3. 使用流操作找到最大子数组和,该和即为最大开销。
 */

import java.util.HashMap;
import java.util.Map;
import java.util.stream.IntStream;

public class Solution {
    public int maximumCostSubstring(String s, String chars, int[] vals) {
        Map<Character, Integer> charValueMap = new HashMap<>();
        for (int i = 0; i < chars.length(); i++) {
            charValueMap.put(chars.charAt(i), vals[i]);
        }
        int[] maxCost = {0};
        int[] currentCost = {0};
        s.chars().forEach(c -> {
            int value = charValueMap.getOrDefault((char) c, c - 'a' + 1);
            currentCost[0] = Math.max(value, currentCost[0] + value);
            maxCost[0] = Math.max(maxCost[0], currentCost[0]);
        });
        return maxCost[0];
    }
}

解释

方法:

The solution implements the Kadane's algorithm to find the maximum sum of a contiguous subarray, where the array elements are the costs of characters in the string 's'. Initially, a dictionary 'd' is created to map each lowercase letter to its alphabetical index. This mapping is then updated with the given 'chars' and their corresponding 'vals'. During the iteration over the string 's', the value of each character is retrieved from the dictionary 'd', and the current sum 'cur' is updated. If 'cur' drops below zero, it is reset to zero. The maximum observed 'cur' is tracked with 'res'. This ensures that we are always considering the maximum cost of any contiguous substring.

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么在计算每个字符的价值时,选择使用Kadane's algorithm来处理子字符串的最大开销?
Kadane's algorithm 是一种有效的算法,用于找出数组中具有最大和的连续子数组。在这个问题中,我们需要找到字符串中某个连续子字符串的最大开销,这与找到最大和的连续子数组的问题本质相同。通过将每个字符转换为其相应的数值开销,我们可以将问题转化为一个典型的最大子数组和问题,从而利用 Kadane's algorithm 来解决。该算法的时间复杂度为O(n),因此在处理大数据量时仍然非常高效。
🦆
在实现中,当当前累积开销`cur`小于0时,直接将其重置为0,这种处理方式的理论依据是什么?
在 Kadane's algorithm 中,如果当前累积开销 `cur` 变为负数,意味着将这部分累积加入到后续的子数组中只会降低其总和。因此,最优的策略是从下一个元素开始重新计算新的子数组和,即将 `cur` 重置为0。这样做是为了确保我们总是从可能增加总和的位置开始计算,从而找到可能的最大子数组和。
🦆
你如何确定字典`d`的更新(使用chars和vals)不会引入重复的键值对,从而影响结果的准确性?
在 Python 中,字典的键是唯一的。当使用 `d.update(zip(chars, vals))` 更新字典时,如果 `chars` 中的字符已经存在于字典 `d` 中,其对应的值将被 `vals` 中相应位置的值覆盖。这确保了每个字符最终都会映射到一个具体的值。因此,即使存在重复的字符更新,也只会影响该字符的最终值,而不会引入重复的键值对。这种处理方式符合题目要求,即可能需要根据 `chars` 和 `vals` 更改特定字符的值。
🦆
如果`chars`包含的字符和`vals`数组的长度不匹配,解决方案中会如何处理这种情况?
在题解中没有特别处理`chars`和`vals`长度不匹配的情况。`zip(chars, vals)`函数将创建一个元组列表,其长度由最短的输入序列决定。如果`chars`比`vals`长,那么超出`vals`长度的部分字符将不会被包含在更新字典的操作中;如果`vals`比`chars`长,那么超出`chars`长度的部分值将被忽略。在实际应用中,应该确保`chars`和`vals`的长度相匹配,或者在代码中添加逻辑来处理长度不匹配的情况,以避免潜在的错误或逻辑问题。

相关问题