BFS and DP -- the 70th biweekly match of Li Kou

Posted by sparrrow on Wed, 02 Feb 2022 18:05:46 +0100

⭐ New pit in winter vacation -- daily question notes of code Fox
First question, greedy thought (take the largest two at a time, and then the largest third for free - the amount of sugar you can take for free is limited. Why not take one expensive one for free)
The second problem is mathematical thinking (all numbers are in a range, so you only need to record the maximum and minimum values. The difference array indicates that each value changes uniformly, and the maximum and minimum values are unified + n/-n; you can find the possibility to meet the range)
The third question, BFS (I have to simplify my code structure and sort out the classic methods 😢)
Question 4, DP (there's nothing to say, not even as good as question 3)

2144. Minimum cost of buying candy at a discount

A shop is selling candy at a discount. Every time you buy two sweets, the store will give you one free candy.

The only limitation of free candy is that its price needs to be less than or equal to the smaller value of the two candy prices purchased.

  • For example, there are four candies with prices of 1, 2, 3 and 4 respectively. If a customer buys candies with prices of 2 and 3, he can get candy with price of 1 for free, but can't get candy with price of 4.

Give you an integer array cost with subscript starting from 0, where cost[i] represents the price of the ith candy. Please return the minimum total cost of obtaining all candy.

class Solution {
    public int minimumCost(int[] cost) {
        Arrays.sort(cost);
        int i=cost.length-1;
        int sum=0;
        while(i>=0){
            sum+=cost[i--];
            if(i>=0)
            sum+=cost[i--];
            if(i>=0){
                i--;
            }
        }
        return sum;
    }
}

2145. Count the number of hidden arrays - Mid

Give you an integer array differences with subscript starting from 0 and length n, which represents the difference between adjacent elements of a hidden array with length n + 1. A more formal expression is: if we record the hidden array as hidden, then differences[i] = hidden[i + 1] - hidden[i].

Give you two integers lower and upper at the same time. They mean that the values of all numbers in the hidden array are between the closed interval [lower, upper].

  • For example,

    differences = [1, -3, 4]
    

    lower = 1
    

    upper = 6
    

    , then the hidden array is a length of

    4
    

    And all values are in

    1
    

    and

    6
    

    (including both).

    • [3, 4, 1, 5] and [4, 5, 2, 6] are all qualified hidden arrays.
    • It does not meet the requirements because it contains elements greater than 6, 6, 6.
    • [1, 2, 3, 4] does not meet the requirements because the difference between adjacent elements does not meet the given data.

Please return the number of qualified hidden arrays. If there is no qualified hidden array, please return 0.

class Solution {
    public int numberOfArrays(int[] differences, int lower, int upper) {
        int max=0;
        int min=0;
        int dp=0;
        for(int i:differences){
            dp+=i;
            if(dp<min){
                min=dp;
            }
            if(dp>max){
                max=dp;
            }
            //Prune, or you may cross the border
            if(upper-lower-(max-min)+1<0){
                return 0;
            }
        }
        return upper-lower-(max-min)+1<0?0:upper-lower-(max-min)+1;
    }
}

2146. K-sample items with the highest ranking in the price range - Mid

Give you a two-dimensional integer array grid with subscript starting from 0. Its size is m x n, which represents the distribution map of items in a store. The meanings of integers in the array are:

  • 0 indicates a wall that cannot be crossed.
  • 1 indicates an empty grid that can pass freely.
  • All other positive integers represent the price of the same item in the grid. You are free to pass through these squares.

It takes one step to go from one grid to the upper, lower, left and right adjacent grids.

At the same time, give you an integer array pricing and start, where pricing = [low, high] and start = [row, col], indicating that your starting position is (row, col), and you are only interested in items whose price is within the closed range [low, high]. And give you an integer k.

You want to know the location of the top k items in a given range. The ranking is based on the following rules from high to low priority:

  1. Distance: defined as the number of steps required for the shortest path from start to an item (higher ranking for closer distances).
  2. Price: items with lower prices have higher priority, but only the prices within a given range are considered.
  3. Row coordinates: smaller row coordinates have higher priority.
  4. Column coordinates: smaller column coordinates have higher priority.

Please return the coordinates of the top k items in the given price, sort them according to the ranking and return. If there are less than k items in a given price, please return all their coordinates.

class Solution {
    public List<List<Integer>> highestRankedKItems(int[][] grid, int[] pricing, int[] start, int k) {
        List<int[]> listAns=new ArrayList<>();
        List<int[]> listCur=new ArrayList<>();
        int countCur=0;
        int countAns=0;
        int m=grid.length;
        int n=grid[0].length;
        int[][] d=new int[][]{{-1,0},{1,0},{0,-1},{0,1}};

        int p=grid[start[0]][start[1]];
        if(p<=pricing[1]&&p>=pricing[0]){
            listAns.add(new int[]{0,p,start[0],start[1]});
            countAns++;
        }
        
        grid[start[0]][start[1]]=0;
        listCur.add(new int[]{start[0],start[1]});
        countCur++;
        int step=0;

        while(!listCur.isEmpty()){
            //countCur the current number of steps and the number of nodes to go through. listCur saves the nodes
            step++;
            int midCount=countCur;
            countCur=0;
            while(midCount-->0){
                int[] curPoint=listCur.remove(0);

                for(int[] i:d){
                    int x=curPoint[0]+i[0];
                    int y=curPoint[1]+i[1];

                    if(x<0||x>=m||y<0||y>=n){
                        continue;
                    }
                    int price=grid[x][y];
                    if(price==0){
                        continue;
                    }

                    if(price>=pricing[0]&&price<=pricing[1]){
                        listAns.add(new int[]{step,price,x,y});
                        countAns++;
                    }

                    grid[x][y]=0;
                    listCur.add(new int[]{x,y});
                    countCur++;
                }
            }

            if(countAns>=k){
                break;
            }
        }

        int[][] listA=new int[listAns.size()][4];
        for(int i=0;i<listAns.size();i++){
            listA[i]=listAns.get(i);
        }
        Arrays.sort(listA,new MyComparator());
        
        List<List<Integer>> ans=new ArrayList<>();
        int need=0;
        for(int[] i:listA){
            List<Integer> mid=new ArrayList<>();
            mid.add(i[2]);
            mid.add(i[3]);
            ans.add(mid);
            if(++need>=k){
                break;
            }
        }
        return ans;
    }

    class MyComparator implements Comparator<int[]>{ 
        public int compare(int[] a, int[] b) {
    	    if(a[0]>b[0]){
                return 1;
            }
            else if(a[0]==b[0]){
                if(a[1]>b[1]){
                    return 1;
                }
                else if(a[1]==b[1]){
                    if(a[2]>b[2]){
                        return 1;
                    }
                    else if(a[2]==b[2]){
                        if(a[3]>b[3]){
                            return 1;
                        }
                    }
                }
            }
            return -1;
   	    }     
    } 
}

2147. Number of schemes for separated corridors - Hard

In the corridor of a library, there are some seats and decorative plants lined up. Give you a string corridor with subscript starting from 0 and length of n, which contains the letters'S' and 'P', where each'S' represents a seat and each 'P' represents a plant.

A screen has been placed to the left of subscript 0 and to the right of subscript n - 1. You need to put some extra screens. At most one screen can be placed between each position i - 1 and i (1 < = i < = n - 1).

Please divide the corridor into several sections with screens, and there are exactly two seats in each section, and the number of plants in each section is not required. There may be a variety of partition schemes. If any of the two schemes has a different screen position, they are regarded as different schemes.

Please return to the number of schemes for dividing the corridor. Since the answer may be large, please return the result of its remainder of 109 + 7. If there is no scheme, please return 0.

class Solution {
    public int numberOfWays(String corridor) {
        int i=0;
        int midCountP=-1;
        long ans=1;
        while(i<corridor.length()){
            //Find two chairs
            int midCountTwoC=0;
            while(midCountTwoC!=2&&i<corridor.length()){
                if(corridor.charAt(i)=='S'){
                    midCountTwoC++;
                }
                i++;
            }
            //If there are not enough two, it means that it is not an even number, it is impossible to score successfully, or there is no chair, and the score method is 0
            if(midCountTwoC!=2){
                return 0;
            }

            //Count the score before the current position
            if(midCountP!=-1)
                ans=(ans*(midCountP+1))%1000000007;
            midCountP=0;

            //Count the number of consecutive plants after this position, and insert the position of the screen + 1
            while(i<corridor.length()){
                if(corridor.charAt(i)=='P'){
                    midCountP++;
                    i++;
                }
                else{
                    break;
                }
            }

        }

        return (int)ans;
    }
}

ending

Title Source: LeetCode link: https://leetcode-cn.com/problems

⭐ Pay attention to the author, take you to brush the questions, and learn the most commonly used algorithm skills from simple algorithm questions (one question per day in winter vacation)
⭐ Pay attention to the author's problem brushing - simple to advanced, which makes you unknowingly become a ruthless problem brushing machine. Please send a private letter if you have any questions

Topics: Algorithm leetcode greedy algorithm Permutation dp