Problem 2288

Abstract / Summary

Given a list of prices and a discount percentage, return each price reduced by that percentage.

Note

The full problem description, including helpful examples, can be found on LeetCode.

Python 2288.py

class Solution:
    def discountPrices(self, sentence: str, discount: int) -> str:
        # convert discount
        factor = (100 - discount) / 100

        def convert():
            for p in sentence.split(" "):
                # starts with "$", no other "$", only digits
                if p and p[0] == "$" and p[1 :].isnumeric():
                    value = float(p[1 :]) * factor
                    yield f"${value:.2f}" # two decimal places
                else:
                    yield p

        return " ".join(convert())
15 lines | 553 bytes | submitted July 11, 2024 | GitHub   27% comment ratio | tab size 4 | low complexity

Difficulty

This problem is ranked as
easy medium hard

and has an acceptance rate of about 34% (90k+ submissions).

Typical patterns to solve this problem:
  • String
I solved 663 easy, 1250 medium and 309 hard problems

AI Disclaimer

Every single line of code was written by me, 100% from scratch, between August 2023 and August 2024.
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.

See this dedicated page for more details.
LeetCode profile | GitHub repo

Code Walkthrough

Overview

The provided Solution class implements a method discountPrices that receives a textual sentence and an integer discount percentage. Its purpose is to locate every token that represents a price-identified by a leading dollar sign followed exclusively by digits-apply the discount, and return the sentence with the discounted prices formatted to two decimal places. Tokens that do not meet the price criteria remain unchanged.

Key Steps

The method begins by converting the discount percentage into a multiplicative factor.

factor = (100 - discount) / 100

A nested generator function convert is defined to iterate over each space-separated token of the input sentence.

def convert():
    for p in sentence.split(" "):
        ...

Inside the loop, the code checks whether a token starts with the character $ and whether the remainder of the token consists solely of numeric characters. The condition p and p[0] == "$" and p[1:].isnumeric() guarantees that empty strings are ignored, the leading character is a dollar sign, and no other characters such as letters or additional symbols appear after the sign.

When the condition is satisfied, the numeric portion is converted to a floating-point value, multiplied by the previously computed factor, and formatted to exactly two decimal places using an f-string.

value = float(p[1:]) * factor
yield f"${value:.2f}"

If the token does not represent a valid price, the original token is yielded unchanged.

else:
    yield p

After the generator has produced all transformed tokens, they are reassembled into a single string with spaces separating them.

return " ".join(convert())

Edge Cases Handled

The implementation explicitly guards against several edge conditions. An empty token resulting from consecutive spaces is safely ignored because the leading p check fails. Tokens that begin with $ but contain non-numeric characters after the sign, such as $12a3 or $-45, are not processed as prices; the isnumeric() call rejects them, leaving the token untouched. Tokens that consist solely of a dollar sign without following digits, for example $, also bypass the discount logic because the numeric slice would be empty and isnumeric() would return False. The formatting step ensures that even whole-number results are displayed with two decimal places, turning a discounted value like 5 into $5.00.

Performance Optimizations

The code leverages a generator (convert) to produce transformed tokens on the fly, avoiding the creation of an intermediate list that would hold all tokens before joining. This streaming approach reduces memory pressure, especially for long sentences. The use of sentence.split(" ") with a single space delimiter avoids the overhead of splitting on arbitrary whitespace, which aligns with the problem’s expectation that tokens are space-separated. Computing the discount factor once outside the loop eliminates repeated arithmetic inside the iteration, ensuring that each token’s processing involves only a single multiplication and a formatting operation. The final join operation concatenates the generator’s output directly, benefiting from Python’s efficient string joining mechanism.

written by openai gpt

ELI5 - Simplified Explanation

Imagine there is a big basket filled with words and prices written on little paper tags. This code is like a helper machine that looks at every single word in a sentence to see if it is a price. A price tag in this basket always starts with a special dollar sign symbol.

The machine takes a discount number, which tells it how much money to take off the top of any price it finds. When the machine sees a word that starts with that dollar sign and has numbers after it, it knows it found a price tag. It takes that number, shrinks it down using the discount, and writes a new price tag with two spots after the decimal point to keep the cents tidy.

If the word does not look like a price tag, the machine just puts it down exactly as it was. Finally, all the new tags and the old words are placed back together in a row into one long line to make a shiny new sentence.

written by google gemini

Code Quality

Several LLMs ranked my code quality on a scale from 1 (very poor) to 10 (outstanding):
n = 27 | median = 8 | μ = 7.56 | σ = 0.92

Complexity Analysis

Time: linear
As a rule of thumb, the maximum input size for one second execution time is
  • factorial: up to 10 elements
  • exponential: up to 20 elements
  • polynomial: a few thousand elements
  • loglinear: up to 100,000 elements
  • linear: a few million elements
  • logarithmic: a billion elements
  • constant: practically unlimited
generated automatically

Other Solutions

I wrote a basic crawler to find other solutions to that problem.
Obviously, I did that after I solved the problem myself.

In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.

And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.

(click on a column header to sort the table)
author
author solutions
www AlgoMonster Java Python C++ TS
WalkCCC Java Python C++
leetcode.ca Java Python C++ Go TS
Progiez Java Python C++
github charles-wangkai Java
everthis JS
JoshCrozier JS
lkwq007 Python
varunu28 Java
AlgoMonster C++, Python, Java, TypeScript
WalkCCC C++, Python, Java
leetcode.ca C++, Go, Java, Python, TypeScript
Progiez C++, Java, Python
charles-wangkai Java
everthis JavaScript
JoshCrozier JavaScript
lkwq007 Python
varunu28 Java
20 links | 9 authors | 6 languages

Videos

6 videos   did my crawler come up with invalid videos ? drop me a line.

Similar Problems

1 similar problem

Solved On The Same Day

9 solutions   July 11, 2024

Extra

There are a few extra pages giving you some insights into my setup:
  • Tech Stack - my development environment and tools
  • AI - how AI helped me create this website (NOT solving the problems)
  • Progress - progression over time
  • Quality - code quality