LeetCode--Summary of Greedy Algorithm Concepts and Analysis of Classic Topics

table of Contents

Introduction to Greedy Algorithm:

Topic 1: Avoid the minimum deletion cost of duplicate letters

Topic 2: The best time to buy stocks 2

Topic 3: Distribute cookies

Topic 4: Jumping game

Topic 5: Use the least number of arrows to detonate the balloon

Topic 6: Reduce the size of the array by half


Introduction to Greedy Algorithm:

It is an algorithm that takes the best or optimal (most advantageous) choice in the current state in each step of the selection, and hopes that the result is the best/optimal algorithm in the world

The difference between greedy algorithm and dynamic programming is that it makes a choice for the solution of each sub-problem and cannot be regressed.

Dynamic programming will save the previous calculation results, and select according to the current, with a rollback function.

Topic 1: Avoid the minimum deletion cost of duplicate letters

(Subject link: https://leetcode-cn.com/problems/minimum-deletion-cost-to-avoid-repeating-letters/ )

Give you a string s and an integer array cost, where cost[i] is the cost of removing the character i from s.

Returns the minimum deletion cost that makes any two adjacent letters of the string different.

Please note that after deleting one character, the cost of deleting other characters will not change.

Example 1:

Input: s = "abaac", cost = [1,2,3,4,5]
Output: 3
Explanation: The cost of deleting the letter "a" is 3, and then you get "abac" (two adjacent letters in the string Not the same).
Example 2:

Input: s = "abc", cost = [1,2,3]
Output: 0
Explanation: There is no need to delete any letters, because there is no case where two adjacent letters are the same in the string.
Example 3:

Input: s = "aabaa", cost = [1,2,3,4,1]
Output: 2
Explanation: Delete the first and last letter to get the string ("aba").

prompt:

s.length == cost.length
1 <= s.length, cost.length <= 10^5
1 <= cost[i] <= 10^4
s contains only lowercase English letters

Idea: Greedy thinking, we find repeated character strings,

And keep the most expensive characters deleted in the string, so greedy everywhere will lead to the best results

Java source code:

public class delete_cost {
    public static void main(String[] args) {
        //String s = "abaaac";
        String s = "aabaa";
        //int[] cost = new int[]{1,2,3,9,4,5};
        int[] cost = new int[]{1,2,3,4,1};
        int costsum = 0;
        int i = 0;
        int second_j =0;
        int length = 0;
        while(i<s.length()-1){
            int flag = 0;
            int cost_max =0;
            length = 0;
            for (int j = i+1; j <s.length() ; j++) {
                if(s.charAt(i) == s.charAt(j)){
                    length = j-i;
                    second_j = j;
                    flag =1;
                    continue;
                }else{
                    break;
                }
            }
            if(flag ==1){
                for(int m = i; m<=second_j;m++){
                    costsum += cost[m];
                    if(cost_max <cost[m]){
                        cost_max = cost[m];
                    }
                }
                costsum = costsum - cost_max;
                i= second_j;
            }else{
                i = i+1; //有的话加length否则加1
            }

        }
        System.out.println("costsum: "+costsum);
    }
}

Topic 2: The best time to buy stocks 2

(Subject link: https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/ )

Given an array, its i-th element is the price of a given stock on the i-th day.

Design an algorithm to calculate the maximum profit you can get. You can complete as many transactions as possible (buying and selling a stock multiple times).

Note: You cannot participate in multiple transactions at the same time (you must sell the previous stocks before buying again).

Example 1:

Input: [7,1,5,3,6,4]
Output: 7
Explanation: Buy on the 2nd day (stock price = 1), and sell on the 3rd day (stock price = 5), This exchange can make a profit = 5-1 = 4.
     Then, buy on the 4th day (stock price = 3), and sell on the 5th day (stock price = 6). This exchange can make a profit = 6-3 = 3 

Idea: Greedy thinking, traversing the entire array, as long as the price is higher than today's one day later, it means that we can buy stocks today and sell stocks the day after tomorrow

So we traverse from the front to the back, and we find that the day after the next day is higher than today, we record it and calculate how much it is higher.

class Solution {
    public int maxProfit(int[] prices) {
        int res = 0;
        for(int i =0;i <prices.length-1;i++){
            if(prices[i] < prices[i+1]){
                res = res+prices[i+1]-prices[i];
            }
        }
        return res;
    }
}

Topic 3: Distribute cookies

(Subject link: https://leetcode-cn.com/problems/assign-cookies/ )

Suppose you are a great parent and want to give your children some biscuits. However, each child can only give one cookie at most.

For each child i, there is an appetite value g[i], which is the smallest size of biscuit that can satisfy the appetite of the children; and each biscuit j has a size s[j]. If s[j] >= g[i], we can assign this cookie j to child i, and this child will be satisfied. Your goal is to satisfy as many children as possible and output this maximum value.
Example 1:

Input: g = [1,2,3], s = [1,1]
Output: 1
Explanation: 
You have three children and two biscuits. The appetite values ​​of the three children are: 1, 2, 3.
Although you have two small biscuits, since their size is 1, you can only satisfy the child whose appetite is 1.
So you should output 1.

Idea: First sort the two arrays from small to large, and then adopt the greedy idea. For each child,

Try to find the smallest cookie in the cookie array that satisfies your child's appetite every time.

class Solution {
    public int findContentChildren(int[] g, int[] s) {
        int res = 0;
        int glength = g.length;
        int slength = s.length;
        Arrays.sort(g);
        Arrays.sort(s);
        int i=0;
        int j=0;
        while (i<glength && j<slength){
            if(s[j] >=g[i]){
                res++;
                i++;
                j++;
            }else{
                j++;
            }
        }
        return res;
    }
}

Topic 4: Jumping game

(Subject link: https://leetcode-cn.com/problems/jump-game/ )

Given an array of non-negative integers, you are initially at the first position of the array.

Each element in the array represents the maximum length you can jump at that position.

Determine whether you can reach the last position.

Example 1:

Input: [2,3,1,1,4]
Output: true
Explanation: We can jump 1 step first, get from position 0 to position 1, and then jump 3 steps from position 1 to the last position.

Idea: Jump from front to back, as long as the current position is less than the farthest position that can continue to jump, we will continue to jump

And how do you ask for the farthest jump? The farthest position before and the farthest position you can go to the current position is the larger value.

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

Topic 5: Use the least number of arrows to detonate the balloon

(Subject link: https://leetcode-cn.com/problems/minimum-number-of-arrows-to-burst-balloons/ )

There are many spherical balloons in two-dimensional space. For each balloon, the input provided is in the horizontal direction,

The start and end coordinates of the balloon diameter. Since it is horizontal, the ordinate is not important,

Therefore, it is enough to know the start and end abscissas. The start coordinate is always smaller than the end coordinate.

A bow and arrow can be shot completely vertically from different points along the x-axis. Shoot an arrow at coordinate x,

If the start and end coordinates of the diameter of a balloon are xstart, xend, and satisfy xstart ≤ x ≤ xend,

Then the balloon will be detonated. There is no limit to the number of bows and arrows that can be shot. Once the bow and arrow are shot,

Can advance indefinitely. We want to find the minimum number of bows and arrows required to detonate all the balloons.

Give you an array of points, where points [i] = [xstart,xend], returns the minimum number of bows and arrows that must be fired to detonate all balloons.
Example 1:

Input: points = [[10,16],[2,8],[1,6],[7,12]]
Output: 2
Explanation: For this example, x = 6 can shoot [2,8] ,[1,6] Two balloons, and x = 11 burst the other two balloons

Official analysis:

To put it succinctly, it is sorted according to the size of the right border, and then each arrow is as far to the right as possible, but the original balloon can still be detonated.

class Solution {
    public int findMinArrowShots(int[][] points) {
        if(points == null || points.length == 0){
            return 0;
        }
        Arrays.sort(points,(a,b)->a[1]>b[1]?1:-1);
        int last = points[0][1];
        int count = 1;
        for(int i =0;i<points.length;i++){
            if(last<points[i][0]){
                count++;
                last = points[i][1];
            }
        }
        return count;
    }
}

[Note]: For sorting similar to two-dimensional arrays, we use:

 Arrays.sort(points, (a,b)->a[1]>b[1] ?1 :-1)

Topic 6: Reduce the size of the array by half

(Subject link: https://leetcode-cn.com/problems/reduce-array-size-to-the-half/ )

Gives you an integer array arr. You can select a set of integers and delete each occurrence of these integers in the array.

Returns the minimum size of the set of integers that can delete at least half of the integers in the array.

Example 1:

Input: arr = [3,3,3,3,5,5,5,2,2,7]
Output: 2
Explanation: Select {3,7} so that the result array is [5,5,5,2,2 ], the length is 5 (half the length of the original array).
The feasible sets of size 2 are {3,5},{3,2},{5,2}.
It is not feasible to choose {2,7}. The result array is [3,3,3,3,5,5,5], and the length of the new array is greater than one-half of the original array.

Idea: Direct violence method, use a hash table to store the number of occurrences of each element, and put the number of times in an array,

Sort the array, and finally traverse the array to find the result that meets the conditions

class Solution {
    public int minSetSize(int[] arr) {
        Map<Integer,Integer> map = new HashMap<Integer,Integer>();
        int[] lengtharr = new int[arr.length];
        int minlength = arr.length/2;
        for(int i =0;i<arr.length;i++){
            if(map.containsKey(arr[i])){
                int tempcount = map.get(arr[i]);
                map.put(arr[i],tempcount+1);
            }else{
                map.put(arr[i],1);
            }
        }
        int k=0;
        int reallength = 0;
        int count = 0;
        for(int key:map.keySet()){
            lengtharr[k++] = map.get(key);
        }
        Arrays.sort(lengtharr);
        for(int i = lengtharr.length - 1 ; i>=0; i--){
            count++;
            reallength = reallength+lengtharr[i];
            if(reallength>=minlength){
                return count;
            }
        }
        return 0;
    }
}

 

Guess you like

Origin blog.csdn.net/yezonghui/article/details/112055512