Analysis of Leetcode Problem Solving Ideas (41) 344-354

  1. Reverse string
    Write a function whose role is to reverse the input string. The input string is given in the form of a character array char[].
class Solution {
    
    
public:
    void reverseString(vector<char>& s) {
    
    
        for (int i = 0, j = s.size() - 1; i < s.size()/2; i++, j--) {
    
    
            swap(s[i],s[j]);
        }
    }
};

  1. Reverse vowels
    Write a function that takes a string as input and reverses the vowels in the string.

Double pointers can be traversed once

class Solution {
    
    
public:
    string reverseVowels(string s) {
    
    
        int i = 0, j = s.length() - 1;
        while (i < j) {
    
    
             if (! isornot(s[i])) {
    
    i ++; continue;} 
             if (! isornot(s[j])) {
    
    j --; continue;} 
             swap (s[i++],s[j--]);
        } 
        return s;
    }
    bool isornot(char c) {
    
    
        return (c == 'a' || c == 'A' || c == 'i' || c == 'I' || c == 'o' || c == 'O' || c == 'u' || c == 'U' || c == 'e' || c == 'E') ;
    }
};

  1. Top K high-frequency elements
    Given a non-empty integer array, return the top k high-frequency elements in it.
    First use the hash table to count the occurrence frequency, then add the smallest heap, and finally remove the elements in the heap
class Solution {
    
    
public:
    static bool cmp(pair<int, int>& m, pair<int, int>& n) {
    
    
        return m.second > n.second;
    }

    vector<int> topKFrequent(vector<int>& nums, int k) {
    
    
        unordered_map<int, int> occurrences;
        for (auto& v : nums) {
    
    
            occurrences[v]++;
        }

        // pair 的第一个元素代表数组的值,第二个元素代表了该值出现的次数
        priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(&cmp)> q(cmp);
        for (auto& [num, count] : occurrences) {
    
    
            if (q.size() == k) {
    
    
                if (q.top().second < count) {
    
    
                    q.pop();
                    q.emplace(num, count);
                }
            } else {
    
    
                q.emplace(num, count);
            }
        }
        vector<int> ret;
        while (!q.empty()) {
    
    
            ret.emplace_back(q.top().first);
            q.pop();
        }
        return ret;
    }
};

  1. Intersection
    of two arrays Given two arrays, write a function to calculate their intersection.
class Solution {
    
    
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
    
    
        unordered_map<int, int> map;
        vector<int> ret;
        for (auto num : nums1)
        {
    
    
            map[num]++;
        }
        for (auto num : nums2)
        {
    
    
            if (map[num])
            {
    
    
                ret.push_back(num);
                map[num] = 0;
            }
        }
        return ret;
    }
};
  1. Intersection of two arrays 2
    Given two arrays, write a function to calculate their intersection.
class Solution {
    
    
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
    
    
        unordered_map<int, int> map;
        vector<int> ret;
        for (auto num : nums1)
        {
    
    
            map[num]++;
        }
        for (auto num : nums2)
        {
    
    
            if (map[num])
            {
    
    
                ret.push_back(num);
                map[num]--;
            }
        }
        return ret;
    }
};
  1. Turn
    the data stream into multiple disjoint intervals. Given a non-negative integer data stream input a1, a2,...,an,..., summarize the numbers seen so far into a list of disjoint intervals.

Every time a number is added, it is first judged whether it is an empty set and whether it is the best leftmost, and then checks whether it is on the edge of a certain set through the dichotomy. Adding a number will affect the merging of the left and right sets at most

class SummaryRanges {
    
    
public:
    vector<vector<int> > intervals;
    /** Initialize your data structure here. */
    SummaryRanges() {
    
    
    }
    int bisearchL(int n) {
    
    
        int lo = 0;
        int hi = intervals.size() - 1;
        while (lo < hi) {
    
    
            int mid = lo + (hi - lo + 1) / 2;
            if (intervals[mid][0] <= n) {
    
    
                lo = mid;
            } else {
    
    
                hi = mid - 1;
            }
        }
        return lo;
    }
    int bisearchR(int n) {
    
    
        int lo = 0;
        int hi = intervals.size() - 1;
        while (lo < hi) {
    
    
            int mid = lo + (hi - lo) / 2;
            if (intervals[mid][1] >= n) {
    
    
                hi = mid;
            } else {
    
    
                lo = mid + 1;
            }
        }
        return hi;
    }
    void addNum(int val) {
    
    
        if (intervals.empty()) {
    
    
            intervals.push_back({
    
    val, val});
            return;
        }
        if (val > intervals.back()[1]) {
    
    
            if (val == intervals.back()[1] + 1) {
    
    
                intervals.back()[1] = val;
            } else {
    
    
                intervals.push_back({
    
    val, val});
            }
        } else if (val < intervals[0][0]) {
    
    
            if (val == intervals[0][0] - 1) {
    
    
                intervals[0][0] = val;
            } else {
    
    
                intervals.insert(intervals.begin(), {
    
    val, val});
            }
        } else {
    
    
            int l = bisearchL(val);
            int r = bisearchR(val);
            if (l == r) return;
            if (intervals[l][1] + 2 == intervals[r][0]) {
    
    
                intervals[l][1] = intervals[r][1];
                intervals.erase(intervals.begin() + r);
            } else if (intervals[l][1] + 1 == val) {
    
    
                intervals[l][1] = val;
            } else if (intervals[r][0] - 1 == val) {
    
    
                intervals[r][0] = val;
            } else {
    
    
                intervals.insert(intervals.begin() + r, {
    
    val, val});
            }
        }
    }
    
    vector<vector<int>> getIntervals() {
    
    
        return intervals;
    }
};


/**
 * Your SummaryRanges object will be instantiated and called as such:
 * SummaryRanges* obj = new SummaryRanges();
 * obj->addNum(val);
 * vector<vector<int>> param_2 = obj->getIntervals();
 */
  1. Matryoshka Envelope Problem
    Given some envelopes with width and height marked, the width and height appear as integer pairs (w, h). When the width and height of another envelope are larger than this envelope, this envelope can be put into another envelope, just like a Russian doll.
    Please calculate the maximum number of envelopes that can form a set of "Russian doll" envelopes (that is, you can put one envelope into another envelope).

Typical dynamic programming problem

class Solution {
    
    
public:
    //优化:动态规划+二分法,时间复杂度O(nlogn),空间复杂度O(n)
    int maxEnvelopes(vector<vector<int>>& envelopes){
    
    
        if(envelopes.empty())return 0;
      //先按w排序,若w相同,则按h由高到低排序;若w不同,则按w由小到大排序
        sort(envelopes.begin(),envelopes.end(),[](const auto& a,const auto& b){
    
    
            return a[0]<b[0]||(a[0]==b[0]&&a[1]>b[1]);
        });
        vector<int> dp;
        for(auto& en:envelopes){
    
    
            int idx=lower_bound(dp.begin(),dp.end(),en[1])-dp.begin();
            if(idx>=dp.size()){
    
    
                dp.emplace_back(en[1]);
            }
            else{
    
    
                dp[idx]=en[1];
            }
        }
        return dp.size();
    }
};

Guess you like

Origin blog.csdn.net/u013354486/article/details/108466314