目录
1、138. 随机链表的复制
2、692. 前K个高频单词
3、349. 两个数组的交集
1、138. 随机链表的复制
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
map<Node*, Node*> copyNodeMap;
Node* cur = head;
Node *copyhead, *copytail;
copyhead = copytail = nullptr;
while (cur) {
Node* copy = new Node(cur->val);
copyNodeMap[cur] = copy;
if (copytail == nullptr) {
copytail = copyhead = copy;
} else {
copytail->next = copy;
copytail = copytail->next;
}
cur = cur->next;
}
cur = head;
Node* copy = copyhead;
while (cur) {
if (cur->random == nullptr) {
copy->random = nullptr;
} else {
copy->random = copyNodeMap[cur->random];
}
cur = cur->next;
copy = copy->next;
}
return copyhead;
}
};
- 代码首先创建一个map(copyNodeMap)用于存储原节点和对应的拷贝节点的映射关系。然后遍历原链表,对每个节点进行拷贝,并将原节点和拷贝节点的映射关系存储到copyNodeMap中。同时,根据拷贝节点的顺序构建新的链表,即将拷贝节点按顺序连接起来。
- 接下来,再次遍历原链表,将拷贝节点的random指针指向对应的拷贝节点。如果原节点的random指针为空,则拷贝节点的random指针也为空;否则,拷贝节点的random指针指向copyNodeMap中对应原节点的拷贝节点。
- 最后,返回拷贝链表的头节点copyHead。
2、692. 前K个高频单词
思路1:使用
map
进行单词计数,然后将计数结果转换为vector
进行排序,最后返回前k个出现次数最多的单词。排序的依据是出现次数,如果出现次数相同,则按照字典顺序排序。
class Solution {
public:
struct Compare {
bool operator()(const pair<string, int>& kv1,
const pair<string, int>& kv2) {
return kv1.second > kv2.second;
}
};
vector<string> topKFrequent(vector<string>& words, int k) {
map<string, int> countMap;
for (auto& a : words) {
countMap[a]++;
}
vector<pair<string, int>> v(countMap.begin(), countMap.end());
//stable_sort保持相同出现次数的单词的相对顺序不变
stable_sort(v.begin(), v.end(), Compare());
vector<string> ret;
for (size_t i = 0; i < k; i++) {
ret.push_back(v[i].first);
}
return ret;
}
};
思路2:或者不使用stable_sort,在仿函数处控制比较逻辑实现单词的相对顺序不变。
class Solution {
public:
struct Compare {
bool operator()(const pair<string, int>& kv1,
const pair<string, int>& kv2) {
return kv1.second > kv2.second ||
(kv1.second == kv2.second && kv1.first < kv2.first);
}
};
vector<string> topKFrequent(vector<string>& words, int k) {
map<string, int> countMap;
for (auto& a : words) {
countMap[a]++;
}
vector<pair<string, int>> v(countMap.begin(), countMap.end());
sort(v.begin(), v.end(), Compare());
vector<string> ret;
for (size_t i = 0; i < k; i++) {
ret.push_back(v[i].first);
}
return ret;
}
};
思路3:通过使用
map
统计单词出现次数,然后使用multiset
进行排序,最后返回出现频率最高的前k个单词。
class Solution {
public:
struct Compare {
bool operator()(const pair<string, int>& kv1,
const pair<string, int>& kv2) const {
return kv1.second > kv2.second ||
(kv1.second == kv2.second && kv1.first < kv2.first);
}
};
vector<string> topKFrequent(vector<string>& words, int k) {
map<string, int> countMap;
for (auto& str : words) {
countMap[str]++;
}
multiset<pair<string, int>, Compare> sortSet(countMap.begin(), countMap.end());
vector<string> ret;
auto it = sortSet.begin();
while (k--) {
ret.push_back(it->first);
++it;
}
return ret;
}
};
3、349. 两个数组的交集
找交集思路:
- 如果两个元素不相等,那么较小的元素向后移动一位。
- 如果两个元素相等,那么它们就是交集的元素,将它们添加到结果中,并将两个指针都向后移动一位。
- 任意一个集合走完则查找结束。
找差集也可以借鉴交集思路:
- 如果两个元素相等,那么它们不是差集的元素,将两个指针都向后移动一位。
- 如果两个元素不相等,那么较小的元素就是差集的元素,将它添加到结果中,并将较小的指针向后移动一位。
- 当其中一个集合的指针走完了,剩下的另一个集合中的元素都是差集的元素。
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
set<int> s1(nums1.begin(), nums1.end());
set<int> s2(nums2.begin(), nums2.end());
auto it1 = s1.begin();
auto it2 = s2.begin();
vector<int> v;
while (it1 != s1.end() && it2 != s2.end()) {
if (*it1 < *it2)
++it1;
else if (*it2 < *it1)
++it2;
else {
v.push_back(*it1);
it1++, it2++;
}
}
return v;
}
};