LeetCode 2086: Minimum Number of Food Buckets to Feed the Hamsters – Java Greedy Solution

Solve the hamster feeding problem using a simple greedy strategy, efficiently placing buckets while detecting impossible arrangements.

Krishna Shrivastava
8 views
LinkedInGithubX
0
0
LeetCode 2086: Minimum Number of Food Buckets to Feed the Hamsters – Java Greedy Solution
Listen to articleAudio version
Ad

Introduction

Some greedy problems look simple at first, but the order in which decisions are made can make a big difference.

In this problem, each 'H' represents a hamster and each '.' represents an empty position where a food bucket can be placed. Every hamster needs at least one bucket immediately to its left or right.

The goal is to feed every hamster using the minimum number of buckets.

The key observation is:

When a hamster needs a bucket, placing it on the right side is generally the best choice because that bucket may also help a future hamster.

This creates a natural left-to-right greedy strategy.

Question Link

LeetCode 2086 – Minimum Number of Food Buckets to Feed the Hamsters

Understanding the Problem

Consider:

H.H

The hamster on the left and the hamster on the right can both use the same bucket:

H 0 H

So only one bucket is required.

But consider:

H..H

One bucket cannot feed both hamsters because they are two positions apart:

H 0 . H

The second hamster still has no adjacent bucket.

Therefore, two buckets are necessary:

H 0 0 H

There is also an impossible case:

HHH

The middle hamster has no empty position next to it, so there is no way to feed it.

Greedy Approach

The string is scanned from left to right.

Whenever a hamster 'H' is encountered:

  1. If it already has a bucket on either side, nothing needs to be done.
  2. Otherwise, if the right position is empty, place a bucket there.
  3. If the right position cannot be used, try the left position.
  4. If both neighboring positions contain hamsters, feeding that hamster is impossible, so return -1.

A character '0' is used to represent a bucket that has already been placed.

Why prefer the right side?

Suppose the current hamster is:

H . H

Placing the bucket on the right side of the current hamster gives:

H 0 H

The next hamster is also fed by the same bucket.

Therefore, choosing the right side can allow one bucket to serve two consecutive hamsters.

Java Solution

The following implementation directly simulates the placement of buckets inside a character array.

class Solution {
public int minimumBuckets(String hams) {

// Special case: a single empty position needs no bucket.
if (hams.length() == 1 && hams.charAt(0) == '.') {
return 0;
}

// A single hamster has no neighboring position.
if (hams.length() == 1 && hams.charAt(0) == 'H') {
return -1;
}

// Convert the string into a character array
// so bucket placements can be marked.
char[] ham = hams.toCharArray();

// Number of buckets placed.
int am = 0;

// Process every position from left to right.
for (int i = 0; i < ham.length; i++) {

if (ham[i] == 'H') {

// Case where the hamster has both left and right neighbors.
if (i > 0 && i < ham.length - 1) {

// If a bucket is already nearby,
// this hamster is already fed.
if (ham[i + 1] == '0' || ham[i - 1] == '0') {
continue;
}

// Both neighbors are hamsters,
// so no bucket can be placed for this hamster.
if (ham[i + 1] == 'H' && ham[i - 1] == 'H') {
return -1;
}

// Prefer placing the bucket on the right.
// This may also feed the next hamster.
if (ham[i + 1] == '.') {
ham[i + 1] = '0';
am++;
}

// If the right side is unavailable,
// place the bucket on the left.
else {
if (ham[i - 1] == '.') {
ham[i - 1] = '0';
am++;
}
}

} else {

// Hamster at the first position.
if (i == 0) {

// Only the right side is available.
if (ham[i + 1] == '.') {
ham[i + 1] = '0';
am++;
} else {

// Another hamster means this hamster
// cannot be fed.
if (ham[i + 1] == 'H') {
return -1;
}
}

} else {

// Hamster at the last position.
if (i == ham.length - 1) {

if (ham[i] == 'H') {

// Only the left side is available.
if (ham[i - 1] == '.') {
ham[i - 1] = '0';
am++;
} else {

// Another hamster means impossible.
if (ham[i - 1] == 'H') {
return -1;
}
}
}
}
}
}
}
}

return am;
}
}

Dry Run

Consider:

hamsters = ".H.H."

Initial array:

. H . H .

First hamster

The hamster at index 1 has:

index 0 → .
index 2 → .

The algorithm prefers the right side.

Place a bucket at index 2:

. H 0 H .

Bucket count:

1

Second hamster

The hamster at index 3 checks its neighbors:

index 2 → 0
index 4 → .

A bucket already exists at index 2, so this hamster is already fed.

No new bucket is required.

Final arrangement:

. H 0 H .

Answer:

1

Another Example

Consider:

H..H

Initially:

H . . H

The first hamster places a bucket on its right:

H 0 . H

The second hamster does not have a bucket next to it, so it places one on its left:

H 0 0 H

Total:

2

Impossible Case

Consider:

.HHH.

The middle hamster has hamsters on both sides:

. H H H .

There is no empty adjacent position for it.

Even if buckets are placed at both ends:

0 H H H 0

the middle hamster still cannot reach a bucket.

Therefore:

-1

Complexity Analysis

Let n be the length of the string.

Time Complexity

The array is traversed once:

O(n)

Each position is processed a constant number of times.

Space Complexity

The string is converted into a character array:

O(n)

Apart from that, only a constant amount of extra variables is used.

Why This Greedy Strategy Works

The important decision is what to do when a hamster has no bucket nearby.

If the right position is empty, placing the bucket there is preferred because:

H . H

becomes:

H 0 H

One bucket now handles two hamsters.

If the bucket were instead placed on the left, the next hamster might still require another bucket.

Therefore, processing from left to right and preferring the right side makes each bucket as useful as possible.

The already placed buckets are marked as '0', allowing later hamsters to immediately recognize that they are already fed.

A Useful Pattern to Remember

This problem is a good example of local greedy decisions producing a globally optimal result.

When a position needs a resource and there are multiple valid choices, ask:

Which choice can also help future elements?

Here, the answer is usually the right-side bucket.

This same type of reasoning appears frequently in greedy problems involving:

  1. Intervals
  2. Arrays
  3. String simulations
  4. Scheduling
  5. Resource placement
  6. Covering neighboring elements

Interview Tip

For an interview, the most important part is not memorizing the implementation.

The core reasoning should be clear:

Hamster already fed → skip

Right side empty → place bucket there

Otherwise left side empty → place bucket there

Both sides are hamsters → impossible

The right-side preference is the key optimization because a bucket can potentially serve the next hamster as well.

Conclusion

LeetCode 2086 is a compact greedy problem where careful local decisions are enough to obtain the minimum number of buckets.

The main idea is to scan from left to right, avoid placing unnecessary buckets, and whenever a bucket is required, prefer the right side whenever possible. Existing buckets are marked directly in the array so that later hamsters can reuse them.

The resulting solution runs in O(n) time, making it easily suitable for the constraint of up to 10⁵ positions.

Ai Assistant Kas