C++ map&setOJ

发布时间:2024年01月17日

目录

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. 两个数组的交集

找交集思路:

  1. 如果两个元素不相等,那么较小的元素向后移动一位。
  2. 如果两个元素相等,那么它们就是交集的元素,将它们添加到结果中,并将两个指针都向后移动一位。
  3. 任意一个集合走完则查找结束。

找差集也可以借鉴交集思路:

  1. 如果两个元素相等,那么它们不是差集的元素,将两个指针都向后移动一位。
  2. 如果两个元素不相等,那么较小的元素就是差集的元素,将它添加到结果中,并将较小的指针向后移动一位。
  3. 当其中一个集合的指针走完了,剩下的另一个集合中的元素都是差集的元素。
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;
    }
};

文章来源:https://blog.csdn.net/m0_73800602/article/details/135632226
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。