Elixir Max Counters
defmodule MaxCounters do
  def max_counters(n, a) do
    condition = n + 1

    {counters, _max_counter, last_update} =
      Enum.reduce(a, {%{}, 0, 0}, fn v, {counters, max_counter, last_update} ->
        cond do
          v <= n ->
            index = v - 1
            updated = max(Map.get(counters, index, 0), last_update) + 1
            {Map.put(counters, index, updated), max(max_counter, updated), last_update}

          v == condition ->
            {counters, max_counter, max_counter}

          true ->
            {counters, max_counter, last_update}
        end
      end)

    0..(n - 1)
    |> Enum.map(fn i -> max(Map.get(counters, i, 0), last_update) end)
  end
end

This delays the expensive “set all counters to max” work until it is really needed, which keeps the solution fast.

Erlang Max Counters
-module(max_counters).
-export([max_counters/2]).

max_counters(N, A) ->
    Condition = N + 1,
    {CountersMap, _MaxCounter, LastUpdate} = lists:foldl(fun(V, {Map, MaxC, Last}) ->
        case V of
            Condition ->
                {Map, MaxC, MaxC};
            _ when V =< N ->
                Index = V - 1,
                NewVal = max(maps:get(Index, Map, 0), Last) + 1,
                {maps:put(Index, NewVal, Map), max(MaxC, NewVal), Last};
            _ ->
                {Map, MaxC, Last}
        end
    end, {#{}, 0, 0}, A),
    [max(maps:get(I, CountersMap, 0), LastUpdate) || I <- lists:seq(0, N - 1)].

This delays the expensive “set all counters to max” work until it is really needed, which keeps the solution fast.

Go Max Counters
func maxCounters(n int, a []int) []int {
	counters := make([]int, n)
	maxCounter := 0
	lastUpdate := 0
	condition := n + 1

	for _, v := range a {
		if v <= n {
			index := v - 1
			if counters[index] < lastUpdate {
				counters[index] = lastUpdate // should already be maxed
			}
			counters[index]++
			if counters[index] > maxCounter {
				maxCounter = counters[index]
			}
		}
		if v == condition {
			lastUpdate = maxCounter
		}
	}

	// apply all max operations to avoid O(M*N) complexity
	for k, v := range counters {
		if v < lastUpdate {
			counters[k] = lastUpdate
		}
	}

	return counters
}

This delays the expensive “set all counters to max” work until it is really needed, which keeps the solution fast.

Haskell Max Counters
import Control.Monad (forM_, when)
import Control.Monad.ST (ST, runST)
import Data.Array.ST (STArray, getElems, newArray, readArray, writeArray)
import Data.STRef (newSTRef, readSTRef, writeSTRef)

maxCounters :: Int -> [Int] -> [Int]
maxCounters n a = runST $ do
  counters <- newArray (0, n - 1) 0 :: ST s (STArray s Int Int)
  maxRef   <- newSTRef 0
  lastRef  <- newSTRef 0
  forM_ a $ \v ->
    if v <= n
      then do
        let idx = v - 1
        lastUpdate <- readSTRef lastRef
        cur        <- readArray counters idx
        let cur' = max cur lastUpdate + 1
        writeArray counters idx cur'
        maxC <- readSTRef maxRef
        when (cur' > maxC) (writeSTRef maxRef cur')
      else
        when (v == n + 1) (readSTRef maxRef >>= writeSTRef lastRef)
  lastUpdate <- readSTRef lastRef
  finalCounters <- getElems counters
  return (map (max lastUpdate) finalCounters)

This delays the expensive “set all counters to max” work until it is really needed, which keeps the solution fast.

Java Max Counters
public class Solution {
    public static int[] maxCounters(int n, int[] a) {
        int[] counters = new int[n];
        int maxCounter = 0;
        int lastUpdate = 0;
        int condition = n + 1;

        for (int v : a) {
            if (v <= n) {
                int index = v - 1;
                if (counters[index] < lastUpdate) {
                    counters[index] = lastUpdate;
                }
                counters[index]++;
                maxCounter = Math.max(counters[index], maxCounter);
            }
            if (v == condition) {
                lastUpdate = maxCounter;
            }
        }

        for (int k = 0; k < counters.length; k++) {
            if (counters[k] < lastUpdate) {
                counters[k] = lastUpdate;
            }
        }

        return counters;
    }
}

This delays the expensive “set all counters to max” work until it is really needed, which keeps the solution fast.

Lisp Max Counters
(defun max-counters (n a)
  (let ((counters (make-array n :initial-element 0))
        (max-counter 0)
        (last-update 0)
        (condition (1+ n)))
    (dolist (v a)
      (when (<= v n)
        (let ((index (1- v)))
          (when (< (aref counters index) last-update)
            (setf (aref counters index) last-update))
          (incf (aref counters index))
          (setf max-counter (max max-counter (aref counters index)))))
      (when (= v condition)
        (setf last-update max-counter)))
    (dotimes (k n)
      (when (< (aref counters k) last-update)
        (setf (aref counters k) last-update)))
    (coerce counters 'list)))

This delays the expensive “set all counters to max” work until it is really needed, which keeps the solution fast.

PHP Max Counters
function maxCounters(int $n, array $a): array
{
    $counters   = array_fill(0, $n, 0);
    $maxCounter = 0;
    $lastUpdate = 0;
    $condition  = $n + 1;

    foreach ($a as $v) {
        if ($v <= $n) {
            $index = $v - 1;
            if ($counters[$index] < $lastUpdate) {
                $counters[$index] = $lastUpdate; // should already be maxed
            }
            $counters[$index]++;
            $maxCounter = $counters[$index] > $maxCounter ? $counters[$index] : $maxCounter;
        }
        if ($v === $condition) {
            $lastUpdate = $maxCounter;
        }
    }

    // apply all max operations to avoid O(M*N) complexity
    foreach ($counters as $k => $v) {
        if ($v < $lastUpdate) {
            $counters[$k] = $lastUpdate;
        }
    }

    return $counters;
}

This delays the expensive “set all counters to max” work until it is really needed, which keeps the solution fast.

Python Max Counters
def max_counters(n: int, a: list[int]) -> list[int]:
    counters = [0] * n
    max_counter = 0
    last_update = 0
    condition = n + 1

    for v in a:
        if v <= n:
            index = v - 1
            if counters[index] < last_update:
                counters[index] = last_update
            counters[index] += 1
            max_counter = max(counters[index], max_counter)
        if v == condition:
            last_update = max_counter

    for k, v in enumerate(counters):
        if v < last_update:
            counters[k] = last_update

    return counters

This delays the expensive “set all counters to max” work until it is really needed, which keeps the solution fast.

Rust Max Counters
fn max_counters(n: i64, a: &[i64]) -> Vec<i64> {
    let mut counters = vec![0i64; n as usize];
    let mut max_counter = 0i64;
    let mut last_update = 0i64;
    let condition = n + 1;

    for &v in a {
        if v <= n {
            let index = (v - 1) as usize;
            if counters[index] < last_update {
                counters[index] = last_update;
            }
            counters[index] += 1;
            max_counter = max_counter.max(counters[index]);
        }
        if v == condition {
            last_update = max_counter;
        }
    }

    for c in counters.iter_mut() {
        if *c < last_update {
            *c = last_update;
        }
    }

    counters
}

This delays the expensive “set all counters to max” work until it is really needed, which keeps the solution fast.

TypeScript Max Counters
function maxCounters(n: number, a: number[]): number[] {
  const counters: number[] = new Array(n).fill(0);
  let maxCounter = 0;
  let lastUpdate = 0;
  const condition = n + 1;

  for (const v of a) {
    if (v <= n) {
      const index = v - 1;
      if (counters[index] < lastUpdate) {
        counters[index] = lastUpdate;
      }
      counters[index]++;
      maxCounter = counters[index] > maxCounter ? counters[index] : maxCounter;
    }
    if (v === condition) {
      lastUpdate = maxCounter;
    }
  }

  return counters.map((v) => (v < lastUpdate ? lastUpdate : v));
}

This delays the expensive “set all counters to max” work until it is really needed, which keeps the solution fast.