在算法领域,贪心算法是一种简单而高效的解题策略。它通过在每一步选择局部最优解,以期达到全局最优解。掌握贪心策略,能让我们在解决某些问题时更加得心应手。本文将揭秘常见问题及实战技巧,帮助你轻松提升算法效率。

贪心算法的基本原理

贪心算法的核心思想是,在每一步选择中都采取当前状态下最好或最优的选择,从而希望导致结果是全局最好或最优的算法。它通常适用于以下几种情况:

  1. 最优子结构:问题的最优解包含其子问题的最优解。
  2. 贪心选择性质:通过局部最优的选择,可以逐步逼近全局最优解。
  3. 问题可被分解:问题可以被分解成若干个相互独立的小问题。

常见问题及实战技巧

1. 活动选择问题

问题描述:给定一系列活动,每个活动有一个开始时间和结束时间。选择一个最大子集,使得这些活动互不冲突。

贪心策略:按照结束时间排序,选择第一个不冲突的活动。

实战技巧:使用优先队列(如Java中的PriorityQueue)维护当前已选择活动的结束时间,遍历所有活动,若当前活动结束时间大于优先队列头部元素,则将其加入队列。

import java.util.PriorityQueue;

public class ActivitySelection {
    public static void main(String[] args) {
        int[] start = {1, 3, 0, 5, 8, 5};
        int[] end = {2, 4, 6, 7, 9, 9};

        PriorityQueue<Integer> pq = new PriorityQueue<>(Comparator.comparingInt(i -> end[i]));
        for (int i = 0; i < end.length; i++) {
            if (pq.isEmpty() || pq.peek() <= start[i]) {
                pq.offer(end[i]);
            }
        }

        while (!pq.isEmpty()) {
            System.out.println(pq.poll());
        }
    }
}

2. 零钱兑换问题

问题描述:给定无限个面值为1、5、10、25的硬币,以及一个总金额n,求最少硬币个数。

贪心策略:优先使用面值最大的硬币。

实战技巧:从大到小遍历硬币面值,每次都尽量使用当前面值最大的硬币。

public class CoinChange {
    public static int coinChange(int[] coins, int amount) {
        Arrays.sort(coins);
        int[] dp = new int[amount + 1];
        dp[0] = 0;
        for (int i = 1; i <= amount; i++) {
            dp[i] = Integer.MAX_VALUE;
            for (int j = 0; j < coins.length; j++) {
                if (coins[j] <= i) {
                    dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
                }
            }
        }
        return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];
    }
}

3. 最长不重复子串

问题描述:给定一个字符串,求最长的无重复字符子串的长度。

贪心策略:使用双指针遍历字符串,维护一个滑动窗口,记录当前窗口内的字符。

实战技巧:使用HashMap记录字符在字符串中的位置,若窗口内出现重复字符,则将左指针移动到重复字符位置之后。

public class LongestSubstring {
    public static int lengthOfLongestSubstring(String s) {
        int[] last = new int[128];
        int ans = 0, start = -1;
        for (int i = 0; i < s.length(); i++) {
            int index = s.charAt(i);
            start = Math.max(start, last[index] + 1);
            ans = Math.max(ans, i - start + 1);
            last[index] = i;
        }
        return ans;
    }
}

总结

掌握贪心策略,能帮助我们高效解决一些算法问题。在实际应用中,要善于观察问题的特点,运用贪心算法的基本原理,结合实战技巧,才能取得更好的效果。希望本文能对你有所帮助。