Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Mastering Array-Based Algorithm Patterns

Tech May 7 4

Jump Game: Greedy Reachability

public boolean canJump(int[] nums) {
    int farthest = 0;
    for (int idx = 0; idx < nums.length; idx++) {
        if (idx > farthest) return false;
        farthest = Math.max(farthest, idx + nums[idx]);
        if (farthest >= nums.length - 1) return true;
    }
    return true;
}

The core idea is to maintain the maximum reachable endex farthest during a single pass. If the current index surpasses farthest, a gap exists, and the end is unreachable. Terminate early once the last index is covered.

Stock Trading: Summing Ascents

public int maxProfit(int[] prices) {
    if (prices.length <= 1) return 0;
    int total = 0;
    int buyDay = 0, sellCandidate = 1;
    while (sellCandidate < prices.length) {
        if (prices[sellCandidate] >= prices[sellCandidate - 1]) {
            sellCandidate++;
        } else {
            if (sellCandidate - 1 > buyDay) {
                total += prices[sellCandidate - 1] - prices[buyDay];
            }
            buyDay = sellCandidate;
            sellCandidate++;
        }
    }
    if (sellCandidate - 1 > buyDay) {
        total += prices[sellCandidate - 1] - prices[buyDay];
    }
    return total;
}

Treat each rising segment as a transaction. Two pointers track the purchase day and the current day. When a drop occurs, book the profit of the completed ascent. A final check handles a trailing rise.

Majority Element: Boyer-Moore Voting

public int majorityElement(int[] nums) {
    int candidate = -1;
    int votes = 0;
    for (int element : nums) {
        if (votes == 0) {
            candidate = element;
            votes = 1;
        } else {
            votes += (element == candidate) ? 1 : -1;
        }
    }
    return candidate;
}

The algorithm cancels out distinct elements. Since the majority appears more than half the time, it survives this elimination process.

H-Index Computation

public int hIndex(int[] citations) {
    int paperCount = citations.length;
    int[] buckets = new int[paperCount + 1];
    for (int c : citations) {
        if (c >= paperCount) buckets[paperCount]++;
        else buckets[c]++;
    }
    int cumulativePapers = 0;
    for (int h = paperCount; h >= 0; h--) {
        cumulativePapers += buckets[h];
        if (cumulativePapers >= h) return h;
    }
    return 0;
}

Bucket citations based on their value. Sweep from the maximum possible H-index downwards, accumulating papers until the count meets the threshold.

Trapping Rain Water: Two-Pointer Bounded Volume

public int trap(int[] height) {
    int left = 0, right = height.length - 1;
    int maxLeft = 0, maxRight = 0;
    int volume = 0;
    while (left < right) {
        if (height[left] < height[right]) {
            maxLeft = Math.max(maxLeft, height[left]);
            volume += maxLeft - height[left];
            left++;
        } else {
            maxRight = Math.max(maxRight, height[right]);
            volume += maxRight - height[right];
            right--;
        }
    }
    return volume;
}

Water trapped at any index is determined by the shorter of the tallest walls to its left and right. Two pointers inward from the ends dynamically update these boundaries.

Zigzag Conversion: Index Mapping by Cycle

public String convert(String s, int numRows) {
    if (numRows == 1) return s;
    StringBuilder output = new StringBuilder();
    int length = s.length();
    int cycle = 2 * numRows - 2;
    for (int row = 0; row < numRows; row++) {
        for (int base = 0; base + row < length; base += cycle) {
            output.append(s.charAt(base + row));
            if (row != 0 && row != numRows - 1 && base + cycle - row < length) {
                output.append(s.charAt(base + cycle - row));
            }
        }
    }
    return output.toString();
}

A full zigzag cycle contains 2*numRows-2 characters. For each row, pick the vertical character and, if applicable, the diagonal character within each cycle.

Text Justification: Distributing White Space

public List<String> fullJustify(String[] words, int maxWidth) {
    List<String> result = new ArrayList<>();
    int idx = 0;
    while (idx < words.length) {
        int start = idx, lineLen = 0;
        while (idx < words.length && lineLen + words[idx].length() + idx - start <= maxWidth) {
            lineLen += words[idx++].length();
        }
        int wordCount = idx - start;
        int totalSpaces = maxWidth - lineLen;

        StringBuilder line = new StringBuilder();
        if (idx == words.length || wordCount == 1) {
            for (int i = start; i < idx; i++) {
                line.append(words[i]);
                if (i < idx - 1) line.append(' ');
            }
            line.append(spaces(maxWidth - line.length()));
        } else {
            int gap = totalSpaces / (wordCount - 1);
            int extra = totalSpaces % (wordCount - 1);
            for (int i = start; i < idx; i++) {
                line.append(words[i]);
                if (i < idx - 1) {
                    int currGap = gap + (extra-- > 0 ? 1 : 0);
                    line.append(spaces(currGap));
                }
            }
        }
        result.add(line.toString());
    }
    return result;
}

private String spaces(int n) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < n; i++) sb.append(' ');
    return sb.toString();
}

Word are gathered greedily until the line is full. For justified lines, base space and extra space are computed from totalSpaces and interval count. The last line is left-aligned with trailing blanks.

Rotating an Array with Reversals

public void rotate(int[] nums, int k) {
    k %= nums.length;
    reverse(nums, 0, nums.length - 1);
    reverse(nums, 0, k - 1);
    reverse(nums, k, nums.length - 1);
}

private void reverse(int[] arr, int start, int end) {
    while (start < end) {
        int temp = arr[start];
        arr[start++] = arr[end];
        arr[end--] = temp;
    }
}

A right rotation by k is equivalent to three reversals: the whole array, the first k elements, and the remaining elements.

Candy Distribution: Two-Way Constraint Satisfaction

public int candy(int[] ratings) {
    int n = ratings.length;
    int[] allocation = new int[n];
    Arrays.fill(allocation, 1);
    for (int i = 1; i < n; i++) {
        if (ratings[i] > ratings[i - 1]) allocation[i] = allocation[i - 1] + 1;
    }
    for (int i = n - 2; i >= 0; i--) {
        if (ratings[i] > ratings[i + 1] && allocation[i] <= allocation[i + 1]) {
            allocation[i] = allocation[i + 1] + 1;
        }
    }
    int total = 0;
    for (int val : allocation) total += val;
    return total;
}

Ensure ascending rating constraints left-to-right, then right-to-left. The final value at each position satisfies both neighbors using minimal candies.

Tags: Arraysgreedy

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.