leetcode_2300 咒语和药水的成功对数

1. 题意

给定两个数组a、b,对于每个a中的元素输出b中能使 a i ∗ b j ≥ s u c c e s s a_i*b_j \ge success aibjsuccess
的个数。
咒语和药水成功对数

2. 题解

2.1 二分

b数组进行排序,找到第一个大于等于
⌈ s u c c e s s a i ⌉ \lceil \frac{success}{a_i}\rceil aisuccess的值,算出其右边还有多少值。

  • 代码一
class Solution {
public:

    vector<int> successfulPairs(vector<int>& spells, vector<int>& potions, long long success)   {
        int sz = spells.size();
        vector<int> ans(sz, 0);
       
        sort(potions.begin(), potions.end());


        for ( int i = 0; i < sz; ++i ) {
            long long tar = (success + spells[i] - 1) / spells[i];

            int dis = distance(lower_bound(potions.begin(), potions.end(), tar),
                            potions.end());
            
            ans[i] = dis;
        }

       
        return ans;
    }
};
  • 代码二
class Solution {
public:

    vector<int> successfulPairs(vector<int>& spells, vector<int>& potions, long long success)   {
        int sz = spells.size();
        vector<int> ans(sz, 0);
       
        sort(potions.begin(), potions.end());


        for ( int i = 0; i < sz; ++i ) {
            long long tar = (success + spells[i] - 1) / spells[i] - 1;

            int dis = distance(upper_bound(potions.begin(), potions.end(), tar),
                            potions.end());
            
            ans[i] = dis;
        }

       
        return ans;
    }
};
  • mine
class Solution {
public:
    int getSucNum(int zval,const vector<int>& pos, long long target) {

        int lo = 0;
        int hi = pos.size() - 1;

        while (lo <= hi) {
            int mid = (lo + hi) >> 1;

            long long mul = 1LL * zval * pos[mid];
            if ( mul >= target)
                hi = mid - 1;
            else
                lo = mid + 1;
        }

        return pos.size() - lo;
    }

    vector<int> successfulPairs(vector<int>& spells, vector<int>& potions, long long success)   {

        int sz = spells.size();
        vector<int> ans( sz, 0);
        sort(potions.begin(), potions.end());

        for (int i = 0; i < sz; ++i) {
            ans[i] = getSucNum(spells[i], potions, success);
        }
        
        return ans;
    }
};
2.2 双指针

a a a数组进行排序得到下标的顺序 i d x idx idx数组,再将 b b b数组从大到小进行排序。
a [ i d x [ i ] ] ∗ b [ j ] ≥ s u c c c s s a[idx[i]] * b[j] \ge succcss a[idx[i]]b[j]succcss时不断移动 j j j,算出此时 a [ i d x [ i ] ] a[idx[i]] a[idx[i]]的药水对数。

  • 代码
class Solution {
public:
 

    vector<int> successfulPairs(vector<int>& spells, vector<int>& potions, long long success)   {
        int sz = spells.size();
        vector<int> ans(sz, 0);
        vector<int> idx(sz, 0);
        iota(idx.begin(), idx.end(), 0);

        sort(idx.begin(), idx.end(),[&spells](int a, int b)->bool
        {
            return spells[a] < spells[b];
        });
        sort(potions.begin(),potions.end(), greater<int>());

        int j = 0;
        int psz = potions.size();
        for (int i = 0; i < sz; ++i) {
            
            for ( ;j < psz;++j) {
                long long res = 1LL * spells[idx[i]] * potions[j];
                if (res < success)
                    break;
            }
            ans[idx[i]] = j;
        }


       
        return ans;
    }
};

你可能感兴趣的:(leetcode,leetcode,算法,职场和发展)