Education + Jobs Hiring Website - 2025
0 like 0 dislike
153 views

ago in Online Assessments by Expert (139,590 points) | 153 views
0 0
import java.util.*;

public class InventoryOptimizerPureO5 {
    static class Interval {
        int start, end, value;

        Interval(int start, int end, int value) {
            this.start = start;
            this.end = end;
            this.value = value;
        }
    }

    public static int minCostO1(int[] quality) {
        if (quality == null || quality.length == 0) return 0;

        List<Interval> intervals = new ArrayList<>();
        // Maps a quality value to its specific Interval object in the list
        Map<Integer, Interval> valueToIntervalMap = new HashMap<>();
        Map<Integer, Integer> freq = new HashMap<>();

        // Single pass: O(n) time complexity
        for (int i = 0; i < quality.length; i++) {
            int val = quality[i];
            freq.put(val, freq.getOrDefault(val, 0) + 1);

            if (!valueToIntervalMap.containsKey(val)) {
                // First time seeing this value.
                // Since 'i' is strictly increasing, intervals are automatically sorted by 'start'!
                Interval newInterval = new Interval(i, i, val);
                intervals.add(newInterval);
                valueToIntervalMap.put(val, newInterval);
            } else {
                // Seen before: Update the end index directly in the existing interval object
                valueToIntervalMap.get(val).end = i;
            }
        }

        // Line sweep to merge overlapping neighborhoods: O(U) time where U <= n
        int totalCost = 0;
        int currentEnd = intervals.get(0).end;
        
        List<Integer> currentGroupVals = new ArrayList<>();
        currentGroupVals.add(intervals.get(0).value);

        for (int i = 1; i < intervals.size(); i++) {
            Interval next = intervals.get(i);

            // Since intervals are naturally sorted by 'start', this check remains 100% correct
            if (next.start <= currentEnd) {
                currentEnd = Math.max(currentEnd, next.end);
                currentGroupVals.add(next.value);
            } else {
                totalCost += calculateGroupCost(currentGroupVals, freq);

                currentEnd = next.end;
                currentGroupVals.clear();
                currentGroupVals.add(next.value);
            }
        }

        totalCost += calculateGroupCost(currentGroupVals, freq);

        return totalCost;
    }

    private static int calculateGroupCost(List<Integer> groupVals, Map<Integer, Integer> freq) {
        int groupTotal = 0;
        int groupMax = 0;
        for (int v : groupVals) {
            int f = freq.get(v);
            groupTotal += f;
            groupMax = Math.max(groupMax, f);
        }
        return groupTotal - groupMax;
    }
}

1 Answer

0 like 0 dislike
import java.util.*;

public class InventoryOptimizerPureO5 {
    static class Interval {
        int start, end, value;

        Interval(int start, int end, int value) {
            this.start = start;
            this.end = end;
            this.value = value;
        }
    }

    public static int minCostO1(int[] quality) {
        if (quality == null || quality.length == 0) return 0;

        List<Interval> intervals = new ArrayList<>();
        // Maps a quality value to its specific Interval object in the list
        Map<Integer, Interval> valueToIntervalMap = new HashMap<>();
        Map<Integer, Integer> freq = new HashMap<>();

        // Single pass: O(n) time complexity
        for (int i = 0; i < quality.length; i++) {
            int val = quality[i];
            freq.put(val, freq.getOrDefault(val, 0) + 1);

            if (!valueToIntervalMap.containsKey(val)) {
                // First time seeing this value.
                // Since 'i' is strictly increasing, intervals are automatically sorted by 'start'!
                Interval newInterval = new Interval(i, i, val);
                intervals.add(newInterval);
                valueToIntervalMap.put(val, newInterval);
            } else {
                // Seen before: Update the end index directly in the existing interval object
                valueToIntervalMap.get(val).end = i;
            }
        }

        // Line sweep to merge overlapping neighborhoods: O(U) time where U <= n
        int totalCost = 0;
        int currentEnd = intervals.get(0).end;
        
        List<Integer> currentGroupVals = new ArrayList<>();
        currentGroupVals.add(intervals.get(0).value);

        for (int i = 1; i < intervals.size(); i++) {
            Interval next = intervals.get(i);

            // Since intervals are naturally sorted by 'start', this check remains 100% correct
            if (next.start <= currentEnd) {
                currentEnd = Math.max(currentEnd, next.end);
                currentGroupVals.add(next.value);
            } else {
                totalCost += calculateGroupCost(currentGroupVals, freq);

                currentEnd = next.end;
                currentGroupVals.clear();
                currentGroupVals.add(next.value);
            }
        }

        totalCost += calculateGroupCost(currentGroupVals, freq);

        return totalCost;
    }

    private static int calculateGroupCost(List<Integer> groupVals, Map<Integer, Integer> freq) {
        int groupTotal = 0;
        int groupMax = 0;
        for (int v : groupVals) {
            int f = freq.get(v);
            groupTotal += f;
            groupMax = Math.max(groupMax, f);
        }
        return groupTotal - groupMax;
    }
}
ago by (220 points)