[Algorithm Notes] Greedy Algorithm

Preface: The learning of greedy algorithm is mainly to increase experience and experience, that is, to do more to accumulate experience, the following will introduce the fun of greedy algorithm through several topics!

Article directory

1. Basic introduction to greedy algorithm

  • It is a local most utilitarian standard, always making the best choice in the current view
  • The difficulty lies in proving that the local most utilitarian criterion can lead to the global optimal solution
  • Greedy in generalsortandheaprelated
  • The difficulty of the greedy algorithm is how to prove that the standard is feasible, but the proof is often difficult, and the logarithm can be used to verify whether the final method is feasible

2. Topics

Question 1: Given an array strs composed of strings, all strings must be concatenated, and the result with the smallest lexicographical order among all possible concatenation results is returned.

Method template: In order to get the result with the smallest lexicographical order, we can sort the array so that the lexicographical order of the string concatenated by the sorted array is the smallest. The collation is for string a and string a + bb b + aafter concatenating and comparing the lexicographical size of the two. If is a + bsmaller , then string a is sorted before string b.

public static class MyComparator implements Comparator<String> {
    
    
    @Override
    public int compare(String o1, String o2) {
    
    
        return (o1 + o2).compareTo(o2 + o1);
    }
}

public static String lowestString(String[] strs) {
    
    
    if (strs == null || strs.length == 0) {
    
    
        return "";
    }
    Arrays.sort(strs, new MyComparator());
    String ans = "";
    for (int i = 0; i < strs.length; i++) {
    
    
        ans += strs[i];
    }
    return ans;
}

Sample code:

public static void main(String[] args) {
    
    
    String[] strs = {
    
    "ba", "b", "cda"};
    System.out.println(lowestString(strs));
}
// 结果为:babcda

Question 2: Some projects need to occupy a conference room for presentations, and the conference room cannot accommodate the presentations of two projects at the same time. Give you the start time and end time of each project, and you can arrange the presentation schedule. The conference room is required to have the most presentations. Returns the most presentations

end time earliest

Method template: When we think about this problem, we may think of using the earliest start time or the shortest preaching time for verification, but this kind of greedy thinking is wrong, the correct way is to think about the problem with the earliest end time. Find the first meeting with the earliest end time, then delete the remaining meetings with a start time earlier than the earliest end time, then find the second meeting with the earliest end time...

public static class Program {
    
    
    public int begin;
    public int end;

    public Program(int begin, int end) {
    
    
        this.begin = begin;
        this.end = end;
    }
}
public static int bestArrange(Program[] programs) {
    
    
    Arrays.sort(programs, new MyComparator());
    int timeLine = 0;
    int count = 0;
    for (int i = 0; i < programs.length; i++) {
    
    
        if (programs[i].begin >= timeLine) {
    
    
            count++;
            timeLine = programs[i].end;
        }
    }
    return count;
}
public static class MyComparator implements Comparator<Program> {
    
    
    @Override
    public int compare(Program o1, Program o2) {
    
    
        return o1.end - o2.end;
    }
}

Sample code:

public static void main(String[] args) {
    
    
    Program[] programs = {
    
     new Program(1, 2), new Program(1, 5), new Program(3, 4), new Program(5, 6) };
    System.out.println(bestArrange(programs));
}
// 结果为:3

Question 3: A gold bar cut in half costs the same amount of copper plate as the length. For example, a gold bar with a length of 20 will cost 20 copper plates no matter how it is cut. A group of people want to divide the whole gold bar, how to divide the most copper plate? Input an array, return the minimum cost of splitting

Example:

For example, given an array {10, 20, 30}, which represents a total of three people, the length of the entire gold bar is 60, and the gold bar needs to be divided into three parts: 10, 20, and 30.

If you first divide the gold bars of length 60 into 10 and 50, it will cost 60; then divide the gold bars of length 50 into 20 and 30, cost 50, and cost 110 copper plates in total

If you first divide the gold bar of length 60 into 30 and 30, it costs 60, and then divide the gold bar of length 30 into 30 and 10, which costs 30, and costs 90 copper plates in total

Method template: When thinking about this question, you may think of cutting with the length of the largest part of the gold bar, but the greedy idea is wrong (if you want to divide it into parts with lengths of 97, 98, 99, and 100, you must first divide the gold bar into 97 parts. +98 and 99+100 parts). Here you can build a small root heap, and then pop up the top two elements and add them together. The result of the addition is the cost of dividing the two gold bars, and then the result is put into the heap, and the above steps are continued until there is only one left in the heap. Numerical value

public static int lessMoney(int[] arr) {
    
    
    Queue<Integer> queue = new PriorityQueue<>();
    for(int num : arr) {
    
    
        queue.add(num);
    }
    int money = 0;
    int cur = 0;
    while(queue.size() > 1) {
    
    
        cur = queue.poll() + queue.poll();
        money += cur;
        queue.add(cur);
    }
    return money;
}

Sample code:

public static void main(String[] args) {
    
    
    int[] arr = {
    
    10, 20, 30};
    System.out.println(lessMoney(arr));
}
// 结果为:90

Question 4: Input: positive number array costs, positive number array profits, positive number K, positive number M. cost[i] represents the cost of item i, profits[i] represents the money that item i can earn after deducting the cost, K represents that you can only do K items in series at most, and M represents your initial funds . Explanation: If you haven't finished a project, the income you get immediately can support you to do the next project. Projects cannot be done in parallel. Output: The maximum amount of money you got last

Method template: You can build a small root heap with project cost from low to high, put all items into the heap, and then build a large root heap with project profit from high to low, and consume less in the small root heap than the current one. The projects with the funds are popped up and added to the big root pile, and the project with the highest profit is selected for purchase, and then the above steps are carried out in turn.

public static class Program {
    
    
    public int cost;
    public int profit;

    public Program(int cost, int profit) {
    
    
        this.cost = cost;
        this.profit = profit;
    }
}

public static class MinCostComparator implements Comparator<Program>{
    
    

    @Override
    public int compare(Program o1, Program o2) {
    
    
        return o1.cost - o2.cost;
    }

}

public static class MaxProfitComparator implements Comparator<Program>{
    
    

    @Override
    public int compare(Program o1, Program o2) {
    
    
        return o2.profit - o1.profit;
    }

}

public static int findMaximizedCapital(int K, int W, int[] profits, int[] capital) {
    
    
    Queue<Program> minCostQ = new PriorityQueue<>(new MinCostComparator());
    Queue<Program> maxProfitQ = new PriorityQueue<>(new MaxProfitComparator());
    for(int i = 0; i < capital.length; i++) {
    
    
        Program program = new Program(capital[i], profits[i]);
        minCostQ.add(program);
    }
    while(K > 0) {
    
    
        while(minCostQ.size() > 0 && minCostQ.peek().cost <= W) {
    
    
            maxProfitQ.add(minCostQ.poll());
        }
        if(maxProfitQ.isEmpty()) {
    
    
            break;
        }
        W += maxProfitQ.poll().profit;
        K--;
    }
    return W;
}

Sample code:

public static void main(String[] args) {
    
    
    int[] capital = {
    
    2,1,6,4};
    int[] profits = {
    
    2,3,1,4};
    int K = 3;
    int W = 1;
    System.out.println(findMaximizedCapital(K,W,profits,capital));
}
// 结果为:10

Question 5: Given a string str, it only consists of 'X' and '.' characters. 'X' means a wall, no lights can be placed, and it does not need to be lit; '.' means a residential area, where lights can be placed and need to be lit. If the lamp is placed at the i position, the three positions i-1, i and i+1 can be lit. Returns at least how many lights are required if all the positions in str that need to be lit are lit

Method template: assuming that the index position is a wall, then index = index+1; when the index position is a settlement, and the index+1 position is a wall, a lamp is required, and index = index+2; when the index position is Residential site, the position of index+1 is a residential site, no matter whether the position of index+2 is a residential site or a wall, a lamp is required, and index = index+3

public static int minLight(String road) {
    
    
    char[] str = road.toCharArray();
    int index = 0;
    int light = 0;
    while(index<str.length) {
    
    
        if(str[index] == 'X') {
    
    
            index++;
        }else {
    
    
            light++;
            if(index+1==str.length) {
    
    
                break;
            }else {
    
    
                if(str[index+1]=='X') {
    
    
                    index=index+2;
                }else {
    
    
                    index=index+3;
                }
            }
        }
    }
    return light;
}

Sample code:

public static void main(String[] args) {
    
    
    String road = "X.XX..X...X....X";
    System.out.println(minLight(road));
}
// 结果为:5

Guess you like

Origin blog.csdn.net/weixin_51367845/article/details/123167925