Given a string s
, calculate its reverse degree.
The reverse degree is calculated as follows:
'a'
= 26, 'b'
= 25, ..., 'z'
= 1) with its position in the string (1-indexed).Return the reverse degree of s
.
Example 1:
Input: s = "abc"
Output: 148
Explanation:
Letter | Index in Reversed Alphabet | Index in String | Product |
---|---|---|---|
'a' |
26 | 1 | 26 |
'b' |
25 | 2 | 50 |
'c' |
24 | 3 | 72 |
The reversed degree is 26 + 50 + 72 = 148
.
Example 2:
Input: s = "zaza"
Output: 160
Explanation:
Letter | Index in Reversed Alphabet | Index in String | Product |
---|---|---|---|
'z' |
1 | 1 | 1 |
'a' |
26 | 2 | 52 |
'z' |
1 | 3 | 3 |
'a' |
26 | 4 | 104 |
The reverse degree is 1 + 52 + 3 + 104 = 160
.
Constraints:
1 <= s.length <= 1000
s
contains only lowercase English letters.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The problem asks us to find the shortest piece of text that contains all the letters of a given word, in any order. The brute force approach involves checking every possible substring of the original text, one by one, to see if it contains all the required letters.
Here's how the algorithm would work step-by-step:
from collections import Counter
def reverse_degree_brute_force(text, word):
# This map holds the counts of each character required by the word.
required_characters_map = Counter(word)
number_of_characters_in_text = len(text)
shortest_valid_length = float('inf')
# We must check every single possible substring of the text.
for start_index in range(number_of_characters_in_text):
for end_index in range(start_index, number_of_characters_in_text):
current_substring = text[start_index : end_index + 1]
substring_character_map = Counter(current_substring)
is_valid_substring = True
# A substring is valid only if it contains at least as many of each required character as the word.
for character, required_count in required_characters_map.items():
if substring_character_map.get(character, 0) < required_count:
is_valid_substring = False
break
if is_valid_substring:
current_length = len(current_substring)
# We track the minimum length found among all valid substrings.
if current_length < shortest_valid_length:
shortest_valid_length = current_length
return shortest_valid_length if shortest_valid_length != float('inf') else -1
The goal is to find the smallest possible section of the text that contains at least one of every character. We can achieve this efficiently by expanding a window from the left until it has all the needed characters, then shrinking it from the left as much as possible while keeping all the characters inside.
Here's how the algorithm would work step-by-step:
def reverse_degree_of_string(text):
# First, determine the set of all unique characters that must be in our window.
target_characters = set(text)
number_of_target_characters = len(target_characters)
if number_of_target_characters == 0:
return 0
left_pointer = 0
characters_in_window_counts = {}
characters_formed_in_window = 0
min_length_found = float('inf')
for right_pointer, current_character in enumerate(text):
characters_in_window_counts[current_character] = characters_in_window_counts.get(current_character, 0) + 1
# When a character's count becomes 1, it means we have just satisfied one of the target characters.
if characters_in_window_counts[current_character] == 1:
characters_formed_in_window += 1
# Once the window is valid (contains all unique characters), we try to shrink it from the left.
while left_pointer <= right_pointer and characters_formed_in_window == number_of_target_characters:
current_window_length = right_pointer - left_pointer + 1
min_length_found = min(min_length_found, current_window_length)
left_character = text[left_pointer]
characters_in_window_counts[left_character] -= 1
# If removing the left character makes the window invalid, we must stop shrinking for this round.
if characters_in_window_counts[left_character] == 0:
characters_formed_in_window -= 1
left_pointer += 1
return min_length_found if min_length_found != float('inf') else 0
Case | How to Handle |
---|---|
Input string is null or empty | The function should return 0 as there are no adjacent pairs to evaluate. |
Input string has only one character | The function should return 0 since a single character cannot form a pair. |
String contains non-alphabetic characters like numbers, symbols, or spaces | These characters should be ignored, and only pairs of adjacent alphabetic characters should be considered for the count. |
An adjacent pair consists of the same letter with different cases (e.g., 'aA' or 'Bb') | This is not a reverse alphabetical pair, so the count should not be incremented. |
String consists of only one repeating character (e.g., 'aaaaa' or 'BBBB') | The function should correctly return 0 as no adjacent characters are reverse alphabetical neighbors. |
String has mixed casing for a valid reverse neighbor pair (e.g., 'Cb' or 'zY') | The case-insensitive comparison logic should correctly identify these as valid pairs and increment the count. |
String contains letters at the boundaries of the alphabet (e.g., 'ba' or 'zy') | The solution must correctly identify 'b' and 'a' or 'z' and 'y' as reverse alphabetical neighbors. |
A very long string that approaches system memory or processing time limits | The solution's linear O(N) time complexity and constant O(1) space complexity ensure it scales efficiently without issues. |