Analyse des idées de résolution de problèmes Leetcode (38) 318-327

  1. Produit de longueur de mot maximale
    Étant donné un tableau de chaînes de mots, recherchez la valeur maximale de longueur (mot [i]) * longueur (mot [j]), et ces deux mots ne contiennent pas de lettres courantes. Vous pouvez considérer chaque mot comme contenant uniquement des lettres minuscules. S'il n'y a pas de tels deux mots, 0 est renvoyé.

Afin de faciliter la comparaison, vous pouvez effectuer des opérations sur les bits pour stocker le champ de bits de chaque mot et les comparer les uns avec les autres via des opérations sur les bits.

class Solution {
    
    
public:
    int str2int(const string& s) {
    
    
        int res = 0;
        for (auto c : s)
            res |= 1 << (c - 'a');
        return res;
    }
    int maxProduct(vector<string>& words) {
    
    
        int N = words.size();
        vector<int> m(N, 0);
        for (int i = 0; i < N; ++i)
            m[i] = str2int(words[i]);
        int res = 0;
        for (int i = 0; i < N; ++i) {
    
    
            for (int j = 0; j < i; ++j) {
    
    
                if ((m[i] & m[j]) == 0 && words[i].size() * words[j].size() > res)
                    res = words[i].size() * words[j].size();
            }
        }
        return res;
    }
};

  1. Interrupteur d'ampoule
    Au départ, n ampoules sont éteintes. Au premier tour, vous allumez toutes les ampoules. Au deuxième tour, vous éteignez toutes les deux ampoules. Au troisième tour, l'interrupteur est commuté toutes les trois ampoules (allumez si éteint, éteignez s'il est allumé). Dans le tour i, l'interrupteur est commuté toutes les ampoules i. Pour le nième tour, vous ne changez que la dernière ampoule. Découvrez combien d'ampoules sont allumées après n tours.

Seul le nombre carré parfait peut satisfaire le nombre impair d'opérations, le problème évolue pour trouver le nombre de 1 ~ n nombres carrés parfaits, 1 * 1, 2 * 2, ..., \ sqrt {n} * \ sqrt {n}, il y a \ sqrt {n} n

class Solution {
    
    
public:
    int bulbSwitch(int n) {
    
    
        return sqrt(n);        
    }
};
  1. Nombre maximum de points

Problème d'algorithme gourmand très classique

class Solution {
    
    
public:
// 返回数组nums中,从idx,到nums.size()-len-1中最大数的索引。
int findMaxIndex(vector<int> &nums, int idx, int len){
    
    	
    int maxIdx = idx;
    for (int i=idx; i<nums.size()-len; i++){
    
    
        if (nums[i] > nums[maxIdx]) maxIdx = i;
    }
    return maxIdx;
}
typedef pair<int,int> P;
vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
    
    
    int n = nums1.size();
    int m = nums2.size();
    set<P> start;	// 存储所有可能的起点索引
    start.insert(pair<int,int>{
    
    0,0});	// 数组1初始起点为0,数组2初始起点为0。
    vector<int> ans;	//存储答案
    while(k){
    
    
        int maxNum = -1;// 第i位数初始值
        set<P> temp;	// 存储第i位数可以导致的所有可能的起点索引
        for(auto p:start){
    
    	// 考虑能够到达第i位的所有可能的起点索引
            int s1 = p.first;
            int s2 = p.second;
            int len1 = max(0, k-(m-s2+1));
            int maxIdx1 = findMaxIndex(nums1, s1, len1);	// 数组1此时能够取的最大数的索引
            int maxNum1 = maxIdx1 >= n ? -1 : nums1[maxIdx1];// 该索引对应的最大数
            if(maxNum1>=maxNum){
    
    
                if(maxNum1>maxNum) temp.clear();	// 如果当前起点索引获得的最大数比之前起点索引获得的最大值还要大,那么之前起点索引得到后续可能索引(temp)可以不用考虑。
                maxNum = maxNum1;
                temp.insert({
    
    maxIdx1+1, s2});	// 更新temp
            }
            int len2 = max(0, k-(n-s1+1));
            int maxIdx2 = findMaxIndex(nums2, s2, len2);
            int maxNum2 = maxIdx2 >= m ? -1 : nums2[maxIdx2];
            if(maxNum2>=maxNum){
    
    
                if(maxNum2>maxNum) temp.clear();
                maxNum = maxNum2;
                temp.insert({
    
    s1, maxIdx2+1});
            }
        }
        ans.push_back(maxNum);	//	确定第i位数
        start.swap(temp);	    //	下一位所有可能的起点索引
        k--;
    }
    return ans;
}
};
  1. Change Exchange
    Compte tenu des pièces de différentes dénominations et d'un montant total. Ecrivez une fonction pour calculer le nombre minimum de pièces nécessaires pour constituer le montant total. Si aucune combinaison de pièces ne peut constituer le montant total, renvoyez -1.

Un problème d'algorithme glouton typique, chaque fois que la dénomination maximale est sélectionnée, puis aucun retour

class Solution {
    
    
public:
    void coinChange(vector<int>& coins, int amount, int c_index, int count, int& ans)
    {
    
    
        if (amount == 0)
        {
    
    
            ans = min(ans, count);
            return;
        }
        if (c_index == coins.size()) return;

        for (int k = amount / coins[c_index]; k >= 0 && k + count < ans; k--)
        {
    
    
            coinChange(coins, amount - k * coins[c_index], c_index + 1, count + k, ans);
        }
    }

    int coinChange(vector<int>& coins, int amount)
    {
    
    
        if (amount == 0) return 0;
        sort(coins.rbegin(), coins.rend());
        int ans = INT_MAX;
        coinChange(coins, amount, 0, 0, ans);
        return ans == INT_MAX ? -1 : ans;
    }
};
  1. Tri Swing 2
    Étant donné un tableau non ordonné nums, réorganisez-le dans l'ordre nums [0] <nums [1]> nums [2] <nums [3] ...

Utilisez la méthode médiane pour diviser en deux tableaux, puis alterner l'épissage. Afin d'atteindre la complexité de l'espace O (1), les adresses virtuelles sont directement mappées sur la baie d'origine au lieu de créer une nouvelle baie

class Solution {
    
    
public:
    void wiggleSort(vector<int>& nums) {
    
    
        int n = nums.size();

        // Find a median.
        auto midptr = nums.begin() + n / 2;
        nth_element(nums.begin(), midptr, nums.end());
        int mid = *midptr;

        // Index-rewiring.
        #define A(i) nums[(1+2*(i)) % (n|1)]

        // 3-way-partition-to-wiggly in O(n) time with O(1) space.
        int i = 0, j = 0, k = n - 1;
        while (j <= k) {
    
    
            if (A(j) > mid)
                swap(A(i++), A(j++));
            else if (A(j) < mid)
                swap(A(j), A(k--));
            else
                j++;
        }
    }
};


  1. Puissance de 3
    Étant donné un entier, écrivez une fonction pour déterminer s'il s'agit d'une puissance de 3.

Questions mathématiques, formules

class Solution {
    
    
public:
    bool isPowerOfThree(int n) {
    
    
    if(n <= 0) return false;
    double a = log10(n) / log10(3) ;        //换底
    return  a == floor(a);         //判断换底后的log3n是否为整数,即n是否为3的倍数
    }
};


  1. Le nombre de sections et
    donné les nombres un tableau d'entiers, et renvoie le nombre d'intervalles entre [inférieur, supérieur], comprenant inférieur et supérieur.
    La somme d'intervalle S (i, j) signifie la somme des éléments de i à j en nombres, y compris i et j (i ≤ j).

La méthode de la somme d'intervalle est apparue plusieurs fois auparavant, qui consiste à enregistrer la somme de chaque position à 0 et à simplement soustraire.

typedef long long LL;
class Solution {
    
    
public:
    
    vector<LL> data;
    vector<int> tr;
    
    // 查找小于等于x的第一个数的下标,找不到返回0
    int binary_search1(LL x) {
    
    
        
        int l = 0, r = data.size() - 1;
        while (l < r) {
    
    
            int mid = l + r + 1 >> 1;
            if (data[mid] <= x) l = mid;
            else r = mid - 1;
        }
        if (l == 0 && data[0] > x) return 0;
        else return l + 1;
    }
    
    // 查找小于x的第一个数的下标,找不到返回0
    int binary_search2(LL x) {
    
    
        int l = 0, r = data.size() - 1;
        while (l < r) {
    
    
            int mid = l + r + 1 >> 1;
            if (data[mid] < x) l = mid;
            else r = mid - 1;
        }
        if (l == 0 && data[0] >= x) return 0;
        else return l + 1;
    }
    
    int lowbit(int x) {
    
    
        return x & -x;
    }
    
    int find(int x) {
    
    
        int ans = 0;
        for (int i = x; i; i -= lowbit(i)) ans += tr[i];
        return ans;
    }
    
    void add(int x, int c) {
    
    
        int n = tr.size() - 1;
        for (int i = x; i <= n; i += lowbit(i)) tr[i] += c;
    }
    
    int countRangeSum(vector<int>& nums, int lower, int upper) {
    
    
        int n = nums.size();
        LL sum = 0;
        vector<LL> s(n);
        for (int i = 0; i < n; i ++) {
    
    
            sum += nums[i];
            s[i] = sum;
        }
        data = s;
        data.push_back(0);
        sort(data.begin(), data.end());
        data.erase(unique(data.begin(), data.end()), data.end());
        tr = vector<int>(data.size() + 1);
        
//         for (int i = 0; i < data.size(); i ++) cout << data[i] << " ";
//         cout << endl;
        int ans = 0;
        int idx_zero = binary_search1(0);
        add(idx_zero, 1);
        for (auto x : s) {
    
    
            LL a = x - upper, b = x - lower;
            int idxa = binary_search2(a), idxb = binary_search1(b);
            int idxx = binary_search1(x);
            // cout << idxa << " " << idxb << " " << idxx << endl;
            if (idxb != 0) {
    
    
                if (idxa == 0) ans += find(idxb);
                else ans += find(idxb) - find(idxa);
            }
            add(idxx, 1);   
            // cout << ans << endl;
        }
        return ans;
    }
};




Je suppose que tu aimes

Origine blog.csdn.net/u013354486/article/details/108093537
conseillé
Classement