Leetcode2300 - Logarithm of successes for spells and potions

What I want to do with this question is to sort the potion array from large to small, and then start to calculate the traversal from large to small. Whenever I find that it cannot be larger, there is no need to think about it later, so I just break, but it still times out:

class Solution {
    
    
public:
    vector<int> successfulPairs(vector<int>& spells, vector<int>& potions, long long success) {
    
    
        sort( potions.begin(), potions.end(), greater<int>());
        // 先从大到小排序
        vector<int> result(spells.size(), 0);
        for(int i = 0; i < spells.size(); i++){
    
    
            for( int j = 0; j < potions.size(); j++){
    
    
                if( (long long)spells[i]*potions[j] >= success){
    
    
                    result[i]++;
                }
                else{
    
    
                    break;
                }
            }
        }
        return result;
    }
};

So the idea in solving the problem is:

First calculate the target value divided by the current poison value to get the minimum potion strength we need, and then operate the position of the value in the potion array, using an algorithm similar to binary search. Or directly use the dichotomy method to find each value and then check whether they can be multiplied with the current poison value to be greater than the target value. It is the same idea, it is a very typical dichotomy method!

I haven't reviewed the relevant chapters on sorting and searching recently, and I still haven't been able to react at once.

class Solution {
    
    
public:
    vector<int> successfulPairs(vector<int>& spells, vector<int>& potions, long long success) {
    
    
        sort( potions.begin(), potions.end());
        for( int & x: spells){
    
    
            long long target = (success - 1) / x;
            if( target < potions.back()){
    
    
                x = potions.end() - upper_bound(potions.begin(), potions.end(), (int) target);
            } else {
    
    
                x = 0;
            }
        }
        return spells;
    }
};

I referred to the writing method of a certain problem solution. Since it was written very concisely, I tried my best to understand the code. Specifically, I paid attention to this line of code:

x = potions.end() - upper_bound(potions.begin(), potions.end(), (int) target);
//如果"target"小于"potions"向量的最后一个元素
//那么将x更新为"potions"向量中大于等于"target"的元素数量。
//这是通过使用二分查找函数"upper_bound"来实现的
//该函数返回指向第一个大于等于给定值的元素的迭代器。
//然后,通过减去这个迭代器与"potions.begin()"之间的距离来计算大于等于"target"的元素数量。

Then I always felt that writing this way was not clear enough, so I wrote it again using the dichotomy method:

class Solution {
    
    
public:
    vector<int> successfulPairs(vector<int>& spells, vector<int>& potions, long long success) {
    
    
        sort( potions.begin(), potions.end());
        vector<int>result;
        for(int i = 0; i < spells.size(); i++){
    
    
            long long target = ( success - 1) / spells[i];
            int left = 0;
            int right = potions.size() - 1;
            while( left <= right){
    
    
                int mid = ( right - left) / 2 + left;
                if((long long) potions[mid] <= target){
    
    
                    left = mid + 1;
                }
                else{
    
    
                    right = mid - 1;
                }
            }
            result.push_back( potions.size() - left );
        }
        return result;
    }
};

Then there are a few points to note:
Why t a r g e t = ( s u c c e s s − 1 ) / s p e l l s [ i ] target= ( success - 1) /spells[i] target=(success1)/spells[i]**:**因为如果是本来目标是查找 p o t i o n s [ i ] > = ⌈ s u c c e s s s p e l l [ i ] ⌉ potions[i] >= \lceil \frac{success}{spell[i]} \rceil potions[i]>=spell[i]success,经过化简即可得: ⌈ s u c c e s s s p e l l [ i ] ⌉ = ⌊ s u c c e s s + s p e l l [ i ] − 1 s p e l l [ i ] ⌋ = ⌊ s u c c e s s − 1 s p e l l [ i ] ⌋ + 1 \lceil \frac{success}{spell[i]} \rceil=\lfloor \frac{success + spell[i] -1}{spell[i]}\rfloor=\lfloor \frac{success-1}{spell[i]} \rfloor+1 spell[i]success=spell[i]success+spell[i]1=spell[i]success1+1, then at this time we only need to let p o t i o n s [ i ] > ⌊ s u c c e s s − 1 s p e l l [ i ] ⌋ potions[i] > \lfloor \frac{success-1}{spell[i]} \rfloor potions[i]>spell[i]success1 can satisfy the above formula of greater than or equal to.
Then after knowing the above search conditions, we are equivalent to finding a value greater than the target value in the array potions t a r g e t target targe The number of elements of t is different in the dichotomy. Every time it is less than or equal to (because we only want to be greater than), we shrink the left boundary and the greater than When the right boundary is reduced, in this case (you can use examples to simulate the two situations, namely the target value is in the array and the target value is not in the array), and finally the number greater than the target value is p o t i o n s . s i z e ( ) − l e f t potions.size() - left potio ns.si from()left

Guess you like

Origin blog.csdn.net/StarandTiAmo/article/details/134360014