- 反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 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]);
}
}
};
- 反转元音字母
编写一个函数,以字符串作为输入,反转该字符串中的元音字母。
双指针遍历一遍即可
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') ;
}
};
- 前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;
}
};
- 两个数组的交集
给定两个数组,编写一个函数来计算它们的交集。
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;
}
};
- 两个数组的交集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;
}
};
- 将数据流变为多个不相交区间
给定一个非负整数的数据流输入 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();
*/
- 俄罗斯套娃信封问题
给定一些标记了宽度和高度的信封,宽度和高度以整数对形式 (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();
}
};