After reading this article, you will not only learn the algorithm routines, but also take the following topics on LeetCode:

870. Advantage shuffle (medium)

-----------

Everyone should have heard the story of Tian Ji's horse racing:

Tian Ji and Qi Wang race horses. The two horses are divided into upper middle and lower third class. If the horses of the same level correspond to the competition, Tian Ji cannot win the Qi Wang. But Tian Ji met Sun Bin, and Sun Bin taught him to use his inferior horse to align the king’s superior horse, then use his own superior horse to align the king’s medium horse, and finally use his own intermediate horse to align the king’s inferior horse. The result was three. Tian Ji won the game with two wins.

Of course, this period of history is also quite interesting. Zou Ji and Tian Ji, who satirized the king's remonstrance and narcissism, were from the same period, and they were later on. But this is a digression, let's stop here.

When I learned Tian Ji’s horse racing text before, I was thinking, if it’s not a three-horse race but a one-hundred-horse race, can Sun Bin arrange the order of the race reasonably and win the King of Qi?

At that time, I didn't come up with any good ideas. I just felt that the core issue was to let yourself take advantage as much as possible and let the other party lose out. To sum up, your own trash and the opponent's elite.

However, I haven't implemented this idea specifically, until recently I brushed up on the 870th problem of "Superior Reshuffle", and at a glance I found that this is an enhanced version of Tian Ji's horse racing problem:

You enter two length equal array nums1 and nums2 , you reorganize nums1 position of elements, making nums1 "advantage" is maximized.

If nums1[i] > nums2[i] , that is nums1 index i on to nums2[i] have "advantages." Maximizing the advantage means that you will reorganize nums1 , nums[i] > nums2[i] as much as possible.

The algorithm signature is as follows:

int[] advantageCount(int[] nums1, int[] nums2);

For example, enter:

nums1 = [12,24,8,32]
nums2 = [13,25,32,11]

Your algorithm should return [24,32,8,12] , because if you arrange nums1 like this, there are three elements that have "advantages".

This is like Tian Ji's horse racing scene, nums1 is Tian Ji's horse, nums2 is Qi Wang's horse, the element in the array is the horse's fighting power, you are Sun Bin, show your true skills .

Thinking about it carefully, the solution to this problem is still a bit confusing. When should I give up resistance to give away the head, and when should I be tough? There should be an algorithm strategy to maximize the "advantage."

Giving away the head must be an expedient measure of last resort, otherwise Tian Ji next door will scold you in a voice. Only when Tian Ji's superior horse is not better than Qi Wang's superior horse, so he will use the inferior horse to exchange with Qi's superior horse.

For more complex issues, you can try to consider special circumstances.

Do you think, who should be the fastest horse of King Ziwang? It must be Tian Ji's fastest horse, we referred to as the number one player.

If Tian Ji’s No. 1 player is no better than Qi Wang’s No. 1 player , then the other horses must have been given for nothing. Obviously, in this case, Tian Ji’s bottom horse must be used to give away the head, reduce one’s losses, preserve strength, and increase access. The winning percentage of the down game.

But if Tian Ji's No. 1 player can compare to Qi Wang's No. 1 player , then he will be just as hard as Qi Wang. Anyway, this Tian Ji can win.

You might say that in this case, maybe Tian Ji's No. 2 player can also do Qi Wang's No. 1 player? If possible, it would be more economical to let the number two player play against Qi Wang's number one player?

Just like, if you can pass the test with 60 points, why do you have to test 61 points? You lose one point for every extra point you take, and it's the most cost-effective to get stuck at 60 points.

This saving strategy is no problem, but it is not necessary. This is also the interesting part of this question, it needs a :

Let’s call Tian Ji’s number one player T1 , number two as T2 , and Qi Wang’s number one as Q1 .

If T2 can win Q1 , you try to save your own strength, let T2 fight Q1 , and keep T1 for whom?

Obviously, you are worried that King Qi still has a horse with a T2 T1 with by 061546a62d9bcd.

But if you think about it carefully, now T2 can beat Q1 , Q1 is Qi Wang’s fastest Maye, how could the remaining Mali of Qi Wang have a better horse T2

Therefore, there is no need to save, the final strategy we came up with is:

Sort Qi Wang and Tian Ji's horses according to their combat effectiveness, and then compare them one by one according to the ranking. If Tian Ji's horse can win, then the game, if not, then change to the bottom to give away the head, save the strength.

The code logic of the above idea is as follows:

int n = nums1.length;

sort(nums1); // 田忌的马
sort(nums2); // 齐王的马

// 从最快的马开始比
for (int i = n - 1; i >= 0; i--) {
    if (nums1[i] > nums2[i]) {
        // 比得过,跟他比
    } else {
        // 比不过,换个垫底的来送人头
    }
}

According to this idea, we need to sort the array of two, but nums2 sequence elements can not be changed, since the order of the calculation result is dependent nums2 order, it can not directly nums2 sort, but to use other data structures to assist.

At the same time, the final solution also uses the two-pointer algorithm template summarized dual-pointer technique summary

int[] advantageCount(int[] nums1, int[] nums2) {
    int n = nums1.length;
    // 给 nums2 降序排序
    PriorityQueue<int[]> maxpq = new PriorityQueue<>(
        (int[] pair1, int[] pair2) -> { 
            return pair2[1] - pair1[1];
        }
    );
    for (int i = 0; i < n; i++) {
        maxpq.offer(new int[]{i, nums2[i]});
    }
    // 给 nums1 升序排序
    Arrays.sort(nums1);

    // nums1[left] 是最小值,nums1[right] 是最大值
    int left = 0, right = n - 1;
    int[] res = new int[n];

    while (!maxpq.isEmpty()) {
        int[] pair = maxpq.poll();
        // maxval 是 nums2 中的最大值,i 是对应索引
        int i = pair[0], maxval = pair[1];
        if (maxval < nums1[right]) {
            // 如果 nums1[right] 能胜过 maxval,那就自己上
            res[i] = nums1[right];
            right--;
        } else {
            // 否则用最小值混一下,养精蓄锐
            res[i] = nums1[left];
            left++;
        }
    }
    return res;
}

The time complexity of the algorithm is well analyzed, that is, the complexity of the binary heap and sorting is O(nlogn) .

At this point, this Tian Ji horse racing problem is solved. The code implementation uses double pointer skills. Starting from the fastest horse, compare it if it is better, and send it if it is not, so that you can get any number of horses. An optimal game strategy.

_____________

View more high-quality algorithm articles Click on my avatar , and I will take you through the buckle by hand, dedicated to making the algorithm clear! My algorithm tutorial has won 90k stars, welcome to like it!

labuladong
63 声望38 粉丝