Skip to content
dsa450for five year olds

Greedy · 13 of 35

Check if it is possible to survive on Island

Stuck on an island where the only shop shuts on Sundays, find the fewest shopping days that keep you fed, or say it cannot be done.

Simple way
time O(S)
room O(1)
Clever way
time O(1)
room O(1)

The problem, simply

You are on an island for S days. Today is Monday. There is one shop. It is open every day except Sunday, and on each visit it sells you at most N units of food. You must eat M units every day, and you can store as much food as you like.

Give back the smallest number of days you need to go shopping to survive all S days, or -1 if you cannot survive. You may shop and then eat on the same day.

A story to remember it

Picture it

grid
MoTuWeThFrSaSuweek 1week 224681012570

S = 9, N = 9, M = 7. Each box is the food left at the end of that day if you shop whenever you still need food. Sunday is closed.

  • done
  • ignored

Examples

A normal case

In
S = 9, N = 9, M = 7
Out
7

You need 9 x 7 = 63 units. Each visit gives at most 9, so 7 visits. Saturday's pile of 12 covers Sunday.

Plenty of food

In
S = 10, N = 16, M = 2
Out
2

You need 20 units. Two visits of 16 cover it, and you never run out.

Shop too small

In
S = 10, N = 20, M = 30
Out
-1

You eat 30 on day 1, but the shop sells only 20.

Starving on the first Sunday

In
S = 13, N = 13, M = 12
Out
-1

There are enough open days in total, but by Sunday you have bought 6 x 13 = 78 and need 7 x 12 = 84.

Short stay

In
S = 6, N = 9, M = 8
Out
6

You leave before Sunday, so the weekly check does not matter. 48 units need 6 visits.

Way 1: the simple way

Live through every day.

  1. Keep food in the pantry and bought so far.
  2. On each day that is not a Sunday, if you have not yet bought S * M in total, buy N and count one shopping day.
  3. Eat M. If food drops below 0, return -1.
  4. After the last day, return the count.

Buying as early as possible is never worse, because stored food does not spoil.

java
class Solution {
    public int minimumDays(int S, int N, int M) {
        long need = (long) S * M;
        long food = 0, bought = 0;
        int days = 0;
        for (int d = 1; d <= S; d++) {
            boolean sunday = d % 7 == 0;          // day 1 is Monday
            if (!sunday && bought < need) {
                food += N;
                bought += N;
                days++;
            }
            food -= M;                            // eat
            if (food < 0) return -1;
        }
        return days;
    }
}

How long it takes: one step per day, O(S). Extra room: a few numbers, O(1).

Way 2: the clever way

Three small checks replace the whole simulation.

  1. If M > N, you starve on day 1. Return -1.
  2. If you stay at least 7 days, the first Sunday is the danger. By then you can have bought at most 6 * N and you have eaten 7 * M. If 6 * N < 7 * M, return -1. If it passes, every later week works the same way, so you never starve.
  3. Otherwise you need S * M units, and each visit gives at most N. The answer is S * M / N rounded up.

Three checks instead of living every day

01 / 06

grid
MoTuWeThFrSaSuweek 1week 2

Example: S = 9 days, the shop sells N = 9, you eat M = 7. Check 1: is M more than N? 7 is not more than 9, so day 1 is safe.

N
9
M
7
  • checking
  • done
  • rejected
  • ignored
java
class Solution {
    public int minimumDays(int S, int N, int M) {
        if (M > N) return -1;                              // starve on day 1
        if (S >= 7 && 6L * N < 7L * M) return -1;          // starve on the first Sunday
        long need = (long) S * M;
        return (int) ((need + N - 1) / N);                 // visits, rounded up
    }
}

How long it takes: a few multiplications, O(1). Extra room: O(1).

Watch out for

  • Day 1 is Monday, so Sundays are days 7, 14, 21, and so on.
  • S * M can be large. Use long before dividing.
  • Round up: (need + N - 1) / N, not need / N.
  • If you stay fewer than 7 days, there is no Sunday, so skip the Sunday check.

What interviewers ask next

  • Why does passing the first Sunday mean every later Sunday is fine? Each full week you can buy 6 * N and eat 7 * M. If one week works, the food left over only grows, week after week.
  • Why is shopping early always best? Food keeps, so having it sooner never hurts. That is why the fewest visits is the rounded up division.
  • What if the pantry can hold at most C units? Then you cannot stock up for Sunday freely. Simulate, buying min(N, C - food) each open day, and the answer can change.
  • What if today is not Monday? Count the open days before the first Sunday and check that open * N >= (open + 1) * M, then use the same weekly check.

Remember this

Grown-up words: the pantry is a running balance, shopping early is a greedy choice, and the weekly check is the invariant that makes the closed form answer safe.