[Greedy] 1405. Longest happy string. M

Posted by nemxu on Mon, 07 Feb 2022 19:13:04 +0100

1. Description

1. If the string does not contain any'aaa','bbb'or'ccc' as a substring, then the string is a'happy string'.
2. Give you three integers a, b, c. Please return any string s that meets all of the following conditions:
s is a happy string as long as possible.
There are at most a letter'a', B letter'b', c letter'c'in s.
s contains only three letters:'a','b','c'.
3. Input: a = 1, b = 1, c = 7
Output: "ccaccbcc" or "ccbccacc"
// 0 <= a, b, c <= 100
// a + b + c > 0

2. Solution

Simply put, given the number of a,b,c characters, let's construct a string that doesn't contain three identical characters together and is as long as possible
1. How to make the longest string
Greedy strategy:
(It's easy to see that more characters are used more than fewer characters to make the longest)
Select the most characters at a time
Scenario 1: Returns the result until each character is zero
Situation 2: When the current character and the first two characters of the string are the same (which will constitute aaa/...), select the second most character to proceed to the next judgment; Returns the result if no other characters are optional
2 How to get the next largest remaining character and the next largest remaining character each time
1. Use collections or arrays to store characters and numbers, use Comparator to define collations, and use the first/second directly (not the third)
2. PriorityQueue (also uses Comparator to define collation)
Priority Queue:

public static void main(String[] args) {

        int a = 1, b = 1, c = 7;
        System.out.println(longestDiverseString(a,b,c));

    }
    
    public static String longestDiverseString(int a, int b, int c) {

        StringBuilder sb = new StringBuilder();
        //Note that Comparator <int[]>() uses int[] type generics, otherwise the method parameter is of type object
//        PriorityQueue<int[]> priorityQueue = new PriorityQueue<>(new Comparator<int[]>() {
//            @Override
//            public int compare(int[] a1, int[] a2) {
//                return a2[0]-a1[0];
//            }
//        });
        //Build a small to large number of priority queues, each time you pick up the largest
        PriorityQueue<int[]> priorityQueue = new PriorityQueue<>((a1, a2) -> a2[0]-a1[0]);
        if (a>0){
            //Int array converts char to int
            priorityQueue.add(new int[]{a,'a'});
        }
        if (b>0){
            priorityQueue.add(new int[]{b,'b'});
        }
        if (c>0){
            priorityQueue.add(new int[]{c,'c'});
        }
        //Exit when queue is empty
        while (!priorityQueue.isEmpty()){
            int[] curChar =priorityQueue.poll();
            int len = sb.length();
            //3 repeats, the first two characters are the same
            if (len>=2&&curChar[1]==sb.charAt(len-1)&&curChar[1]==sb.charAt(len-2)){
                //No other characters, return directly
                if (priorityQueue.isEmpty()){
                    break;
                }
                int[] nextChar = priorityQueue.poll();
                sb.append((char)nextChar[1]);
                //This character will not be put back unless it remains greater than 0
                if ((--nextChar[0])!=0){
                    priorityQueue.add(nextChar);
                }
                //Play back unused char s
                priorityQueue.add(curChar);
            }else {
                //No more than 3 repeats
                sb.append((char)curChar[1]);
                if ((--curChar[0])!=0){
                    priorityQueue.add(curChar);
                }
            }
        }
        return sb.toString();
    }

81 13 O(n∗k∗logC) O(1)

Tips

1.Comparator:
public interface Comparator
Used to sort a set, simply add this to the set to sort it automatically
Mainly his compare()
Collation:

Make compare (x, y) <= 0, that is, the result returned by two elements <=0 is in positive order and can be implemented internally as needed
If you want the maximum to be in front here, subtract the number of elements behind from the number of elements in front, because the latter element is smaller than the former element and is in negative and positive order, otherwise the latter element is larger than the former element and is in the exchange order
2.PriorityQueue
Ordered queues, the order can be customized
Logical structure is binary tree

Other

In fact, as long as you can get the maximum and the second maximum, you can get results, which takes time to beat 100%, but is cumbersome and not elegant

public static String longestDiverseString1(int a, int b, int c) {

        StringBuilder sb = new StringBuilder();
        while(true){
            char curChar = getMaxNumChar(a,b,c);
            if (curChar==' '){
                break;
            }
            int len = sb.length();
            if (len>=2&&curChar==sb.charAt(len-1)&&curChar==sb.charAt(len-2)){
                if (curChar=='a'){
                    a=a-101;
                }else if (curChar=='b'){
                    b=b-101;
                }else {
                    c=c-101;
                }
                char nextChar = getMaxNumChar(a,b,c);
                if (nextChar==' '){
                    break;
                }
                sb.append(nextChar);
                if (nextChar=='a'){
                    a=a-1;
                }else if (nextChar=='b'){
                    b=b-1;
                }else {
                    c=c-1;
                }
                if (curChar=='a'){
                    a=a+101;
                }else if (curChar=='b'){
                    b=b+101;
                }else {
                    c=c+101;
                }
            }else {
                sb.append(curChar);
                if (curChar=='a'){
                    a=a-1;
                }else if (curChar=='b'){
                    b=b-1;
                }else {
                    c=c-1;
                }
            }
        }
        return sb.toString();
    }

    //abc acb cab cba bac bca |A(3,3)
    public static char getMaxNumChar(int a, int b, int c){
        if (a>0&&a>=b&&a>c){
            return 'a';
        }else if(b>0&&b>=a&&b>=c) {
            return 'b';
        }else if(c>0){
            return 'c';
        }
        return ' ';
    }

Topics: Algorithm data structure greedy algorithm