From 95d92ae00d323dc0987e11e5e65ce29c4c36eae6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 4 Jun 2026 05:21:17 +0000 Subject: [PATCH] feat: add solution for 3751. Total Waviness of Numbers in Range I --- .../analysis.md | 59 +++++++++++++ .../problem.md | 86 +++++++++++++++++++ .../solution.go | 47 ++++++++++ .../solution_test.go | 30 +++++++ 4 files changed, 222 insertions(+) create mode 100644 problems/3751-total-waviness-of-numbers-in-range-i/analysis.md create mode 100644 problems/3751-total-waviness-of-numbers-in-range-i/problem.md create mode 100644 problems/3751-total-waviness-of-numbers-in-range-i/solution.go create mode 100644 problems/3751-total-waviness-of-numbers-in-range-i/solution_test.go diff --git a/problems/3751-total-waviness-of-numbers-in-range-i/analysis.md b/problems/3751-total-waviness-of-numbers-in-range-i/analysis.md new file mode 100644 index 0000000..94447e0 --- /dev/null +++ b/problems/3751-total-waviness-of-numbers-in-range-i/analysis.md @@ -0,0 +1,59 @@ +# 3751. Total Waviness of Numbers in Range I + +[LeetCode Link](https://leetcode.com/problems/total-waviness-of-numbers-in-range-i/) + +Difficulty: Medium +Topics: Math, Dynamic Programming, Enumeration +Acceptance Rate: 85.1% + +## Hints + +### Hint 1 + +Start by reading the constraint carefully: `1 <= num1 <= num2 <= 10^5`. That upper bound is tiny — at most about 100,000 numbers to consider. Before reaching for anything clever, ask whether you can simply *visit every number* in the range and measure its waviness directly. The topic tags (Math, DP, Enumeration) hint at a more scalable technique, but for this "I" version the range is small enough that direct enumeration is comfortably fast. + +### Hint 2 + +The real sub-problem is: given a single number, how do you count its peaks and valleys? Turn the number into its sequence of digits. A digit only qualifies if it has *two* neighbors, so you only ever inspect interior positions `i` from `1` to `len-2`. For each interior digit compare it against its left and right neighbor — that's a constant-size local check, no extra data structure needed. + +### Hint 3 + +The definitions are strict and symmetric: a position contributes `+1` if `digit[i] > digit[i-1] && digit[i] > digit[i+1]` (a peak) **or** `digit[i] < digit[i-1] && digit[i] < digit[i+1]` (a valley). Equality on either side disqualifies the position entirely. Sum that contribution across all interior positions to get one number's waviness, then sum that over the whole range. Any number with fewer than 3 digits has no interior position and therefore contributes `0` automatically — the loop just never executes. + +## Approach + +We solve the "I" variant by **direct enumeration** because the range size is bounded by `10^5`. + +1. **Per-number waviness.** Write a helper that takes an integer `n` and returns its waviness: + - Extract the digits. The cleanest way is to repeatedly take `n % 10` and `n /= 10`, which produces digits least-significant first; push them into a slice. (The peak/valley test is symmetric under reversal, so the digit order doesn't actually affect the count, but keeping them in natural order makes the logic easy to reason about.) + - If there are fewer than 3 digits, return `0`. + - For each interior index `i` (`1 <= i <= len-2`), check whether `digit[i]` is strictly greater than both neighbors (peak) or strictly less than both neighbors (valley). Add `1` for each such position. + +2. **Sum over the range.** Loop `x` from `num1` to `num2` inclusive, accumulate `waviness(x)`. + +**Why it works:** waviness is defined purely locally — each interior digit independently is or isn't a peak/valley — so summing local contributions is exactly the definition. Enumerating every number guarantees we never miss or double-count any contribution. + +**Worked example (`num1 = 198, num2 = 202`):** +- `198` → digits `[1,9,8]`, interior `i=1`: `9 > 1 && 9 > 8` → peak → `1`. +- `199`, `200` → no qualifying interior digit → `0`. +- `201` → digits `[2,0,1]`, `i=1`: `0 < 2 && 0 < 1` → valley → `1`. +- `202` → digits `[2,0,2]`, `i=1`: `0 < 2 && 0 < 2` → valley → `1`. + +Total `= 1 + 1 + 1 = 3`. ✅ + +**Scaling note (honest about difficulty):** the "II" style of this problem would push the bound far beyond `10^5`, where enumeration is hopeless. That is where **digit DP** comes in: you count, over all numbers `<= N`, the total waviness by walking digit positions while tracking the previous two digits and a "tight"/"started" state, then answer the range query as `f(num2) - f(num1 - 1)`. It's a satisfying but considerably trickier technique. For *this* problem you don't need it — but it's the natural next step if you want to stretch. + +## Complexity Analysis + +Let `R = num2 - num1 + 1` be the count of numbers in the range and `D` the number of digits (`D <= 6` here). + +Time Complexity: O(R · D) — for each of `R` numbers we do an `O(D)` digit scan. With `R <= 10^5` and `D <= 6` this is well under a million operations. +Space Complexity: O(D) — a single reusable digit buffer per number; everything else is scalar accumulation. + +## Edge Cases + +- **Numbers with fewer than 3 digits** (e.g. `1`–`99`): no interior position exists, waviness is `0`. The interior loop simply doesn't run — no special-casing required, but worth confirming the bounds are `1..len-2`. +- **`num1 == num2`** (single-element range, e.g. Example 3 `4848`): the outer loop runs exactly once; make sure the loop is inclusive on both ends. +- **Plateaus / equal neighbors** (e.g. `121` vs `122`, or `2002`): equality must *not* count. Using strict `>` and strict `<` handles this; a digit equal to a neighbor is neither a peak nor a valley. +- **Both a peak and a valley in one number** (e.g. `4848` → waviness `2`): a single number can contribute more than `1`; accumulate per interior position rather than stopping at the first hit. +- **Leading-digit / trailing-digit positions**: the first and last digits can never qualify by definition; the `1..len-2` interior range enforces this for free. diff --git a/problems/3751-total-waviness-of-numbers-in-range-i/problem.md b/problems/3751-total-waviness-of-numbers-in-range-i/problem.md new file mode 100644 index 0000000..f3372f1 --- /dev/null +++ b/problems/3751-total-waviness-of-numbers-in-range-i/problem.md @@ -0,0 +1,86 @@ +--- +number: "3751" +frontend_id: "3751" +title: "Total Waviness of Numbers in Range I" +slug: "total-waviness-of-numbers-in-range-i" +difficulty: "Medium" +topics: + - "Math" + - "Dynamic Programming" + - "Enumeration" +acceptance_rate: 8506.8 +is_premium: false +created_at: "2026-06-04T05:19:33.663023+00:00" +fetched_at: "2026-06-04T05:19:33.663023+00:00" +link: "https://leetcode.com/problems/total-waviness-of-numbers-in-range-i/" +date: "2026-06-04" +--- + +# 3751. Total Waviness of Numbers in Range I + +You are given two integers `num1` and `num2` representing an **inclusive** range `[num1, num2]`. + +The **waviness** of a number is defined as the total count of its **peaks** and **valleys** : + + * A digit is a **peak** if it is **strictly greater** than both of its immediate neighbors. + * A digit is a **valley** if it is **strictly less** than both of its immediate neighbors. + * The first and last digits of a number **cannot** be peaks or valleys. + * Any number with fewer than 3 digits has a waviness of 0. + +Return the total sum of waviness for all numbers in the range `[num1, num2]`. + + + +**Example 1:** + +**Input:** num1 = 120, num2 = 130 + +**Output:** 3 + +**Explanation:** + +In the range `[120, 130]`: + + * `120`: middle digit 2 is a peak, waviness = 1. + * `121`: middle digit 2 is a peak, waviness = 1. + * `130`: middle digit 3 is a peak, waviness = 1. + * All other numbers in the range have a waviness of 0. + + + +Thus, total waviness is `1 + 1 + 1 = 3`. + +**Example 2:** + +**Input:** num1 = 198, num2 = 202 + +**Output:** 3 + +**Explanation:** + +In the range `[198, 202]`: + + * `198`: middle digit 9 is a peak, waviness = 1. + * `201`: middle digit 0 is a valley, waviness = 1. + * `202`: middle digit 0 is a valley, waviness = 1. + * All other numbers in the range have a waviness of 0. + + + +Thus, total waviness is `1 + 1 + 1 = 3`. + +**Example 3:** + +**Input:** num1 = 4848, num2 = 4848 + +**Output:** 2 + +**Explanation:** + +Number `4848`: the second digit 8 is a peak, and the third digit 4 is a valley, giving a waviness of 2. + + + +**Constraints:** + + * `1 <= num1 <= num2 <= 105` diff --git a/problems/3751-total-waviness-of-numbers-in-range-i/solution.go b/problems/3751-total-waviness-of-numbers-in-range-i/solution.go new file mode 100644 index 0000000..3df44ed --- /dev/null +++ b/problems/3751-total-waviness-of-numbers-in-range-i/solution.go @@ -0,0 +1,47 @@ +package main + +// 3751. Total Waviness of Numbers in Range I +// +// Approach: direct enumeration. The range is bounded by 10^5, so we visit +// every number in [num1, num2] and sum its waviness. The waviness of a single +// number is computed by a local scan over its interior digits: a position is a +// peak if it is strictly greater than both neighbors, a valley if strictly less +// than both. The first and last digits, and any number with fewer than 3 +// digits, contribute nothing because they have no interior position. +// +// Time: O(R * D) where R = num2-num1+1 and D = digit count (<= 6). +// Space: O(D) for a reusable digit buffer. + +// totalWaviness returns the sum of waviness over all integers in [num1, num2]. +func totalWaviness(num1 int, num2 int) int { + total := 0 + for x := num1; x <= num2; x++ { + total += waviness(x) + } + return total +} + +// waviness counts the peaks and valleys of a single non-negative integer. +func waviness(n int) int { + // Extract digits (least-significant first). The peak/valley test is + // symmetric, so order does not affect the count. + digits := make([]int, 0, 7) + if n == 0 { + digits = append(digits, 0) + } + for n > 0 { + digits = append(digits, n%10) + n /= 10 + } + + count := 0 + for i := 1; i+1 < len(digits); i++ { + left, mid, right := digits[i-1], digits[i], digits[i+1] + if mid > left && mid > right { // peak + count++ + } else if mid < left && mid < right { // valley + count++ + } + } + return count +} diff --git a/problems/3751-total-waviness-of-numbers-in-range-i/solution_test.go b/problems/3751-total-waviness-of-numbers-in-range-i/solution_test.go new file mode 100644 index 0000000..225ceb0 --- /dev/null +++ b/problems/3751-total-waviness-of-numbers-in-range-i/solution_test.go @@ -0,0 +1,30 @@ +package main + +import "testing" + +func TestSolution(t *testing.T) { + tests := []struct { + name string + num1 int + num2 int + expected int + }{ + {"example 1: range [120, 130]", 120, 130, 3}, + {"example 2: range [198, 202]", 198, 202, 3}, + {"example 3: single number 4848 has peak and valley", 4848, 4848, 2}, + {"edge case: all numbers fewer than 3 digits", 1, 99, 0}, + {"edge case: single 2-digit number has no interior", 42, 42, 0}, + {"edge case: plateau equal neighbors do not count (121 vs 122)", 122, 122, 0}, + {"edge case: 121 middle is a peak", 121, 121, 1}, + {"edge case: 2002 equal interior neighbors count nothing", 2002, 2002, 0}, + {"edge case: 1213 has peak then valley", 1213, 1213, 2}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := totalWaviness(tt.num1, tt.num2); got != tt.expected { + t.Errorf("totalWaviness(%d, %d) = %d, want %d", tt.num1, tt.num2, got, tt.expected) + } + }) + } +}