leetcode解题思路分析(四十一)344 - 354 题

  1. 反转字符串
    编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 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. 反转元音字母
    编写一个函数,以字符串作为输入,反转该字符串中的元音字母。

双指针遍历一遍即可

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. 前K个高频元素
    给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
    先用哈希表统计出现频率,然后加入最小堆,最后取出堆中元素即可
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. 两个数组的交集
    给定两个数组,编写一个函数来计算它们的交集。
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. 两个数组的交集2
    给定两个数组,编写一个函数来计算它们的交集。
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. 将数据流变为多个不相交区间
    给定一个非负整数的数据流输入 a1,a2,…,an,…,将到目前为止看到的数字总结为不相交的区间列表。

每次加入数字,首先判断是否是空集合,是否在最左最优,然后再通过二分法查看是否在某集合边缘。加入一个数字最多会影响左边和右边两个集合合并

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. 俄罗斯套娃信封问题
    给定一些标记了宽度和高度的信封,宽度和高度以整数对形式 (w, h) 出现。当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。
    请计算最多能有多少个信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。

典型动态规划问题

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();
    }
};

猜你喜欢

转载自blog.csdn.net/u013354486/article/details/108466314
354