You’re building a TikTok-style video feed for a consumer fintech app with 10M+ DAUs. The feed can contain millions of items, and rendering all rows at once would blow up memory and tank scroll performance. To keep the UI smooth, the client uses list virtualization: only items that intersect the viewport (plus a small buffer) are rendered.
Implement the core virtualization routine.
You are given:
heights: an array where heights[i] is the pixel height of item i (variable-height rows)viewport_height: the viewport height in pixelsscroll_top: the current scroll offset in pixels from the top of the listoverscan: number of extra items to render before and after the visible rangeReturn a tuple (start_index, end_index, top_padding, bottom_padding) where:
start_index and end_index define the inclusive range of items to render after applying overscantop_padding is the total height (pixels) of items strictly before start_indexbottom_padding is the total height (pixels) of items strictly after end_index[scroll_top, scroll_top + viewport_height).0 <= start_index <= end_index < n.heights is empty, return (0, -1, 0, 0).Input:
heights = [20, 30, 10, 40]viewport_height = 25scroll_top = 15overscan = 1Output:
(0, 2, 0, 40)Explanation:
[0,20), item1 [20,50), item2 [50,60), item3 [60,100).[15,40), so visible items are 0 and 1.[0..2].top_padding = 0 (nothing before index 0), bottom_padding = 40 (item3).Input:
heights = [100, 100, 100]viewport_height = 50scroll_top = 260overscan = 0Output:
(2, 2, 200, 0)Explanation:
[260,310) intersects only item2 [200,300).0 <= n <= 2 * 10^51 <= heights[i] <= 10^60 <= viewport_height <= 10^90 <= scroll_top <= 10^120 <= overscan <= 10^5n; avoid scanning linearly per scroll event.heights does not change during this call (no dynamic inserts/removals).