692. 前K个高频单词

117 阅读3分钟

692. 前K个高频单词 - 力扣(LeetCode)

image.png

因为map有去重和排序的作用,那我们就用map把 ["i", "love", "leetcode", "i", "love", "coding"]过一遍

然后看看变成了什么样子:

	string words[] = {"i", "love", "leetcode", "i", "love", "coding"};
	map<string, int>m;

	//遍历

	for (auto &str : words) {
		m[str]++;
	}

	for (  auto &kv : m) {
		cout << kv.first << ":" << kv.second << endl;
	}

image.png

我们发现并不是按value值进行排序的

value值:
1 1 2 2
并不是有序排序

观察过后,发现这是对key值进行排序的:

key值:
coding  
i 
leetcode 
love
即按key值的字典进行排序

那我们现在要做的就是按照value再排一次:

 i 2
 love 2
 leetcode 2
 coding 1
 这样就达到了题目要求

可不可以用sort来排呢?

试一下:

sort(m.begin(),m.end());

报错: image.png

我们知道vector是双向迭代器,我们可以借助vetcor进行sort排序:

   vector<pair<string,int>>vv(m.begin().m.end());
   
   
    sort(vv.begin(),vv.end());
在这个代码中,map的元素类型是pair<string,int>,其中键是string类型,值是int类型。因此,如果要将map中的所有键值对存储到vector中,vector的元素类型应该与map的元素类型相同,即pair<string,int>。这样才能确保vector中的元素与map中的键值对一一对应。

打印出来看看:

	string words[] = {	"i", "love", "leetcode", "i", "love", "coding"};
	map<string, int>m;

	//遍历

	for (auto &str : words) {
		m[str]++;
	}

	vector<pair<string, int>>vv(m.begin(), m.end());

	sort(vv.begin(), vv.end());

	for (  auto kv : vv) {
		cout <<  kv.first << " " << kv.second  << endl;
	}

image.png

为什么没变化呀,经过了sort排序但是顺序却没变化。 sort的条件是是参数要可以进行大小比较。 而参数类型是pair,pair是可以比较大小的,如下图,运算符重载: image.png

pair的运算符重载也是先写来了Operator<和operatore=,剩下的复用

然后我们看一下pair是怎么进行比较的: 总结一句话就是first和second有一个小,就小。

这不是我们想要的结果,我们想要它按照second进行排序,sennd大的就排在前面,因此我们可以自己写一个pair的仿函数。来实现一下这个功能:

    bool operator()(const pair<string,int>&kv1,const pair<string,int>& kv2)
    {
        return kv1.second>kv2.second;
    }
    

但是报了一个编译错误: image.png

原因:

image.png

解决办法: 把它放到一个内部类里面:

    struct aa
    {
          bool operator()(const pair<string,int>&kv1,const pair<string,int>& kv2)
    {
        return kv1.second>kv2.second;
    }
    };
  

返回值:

因为题目给的接口类型是vector(string):

image.png 所以我们要再写个vector容易存放返回值,返回值为vv.first:


     vector<string> v; 
    for(size_t i=0;i<k;i++)
    {
        v.push_back(vv[i].first);

    }

报错: image.png

分析: 我们打印出来看看:

                for (  auto kv : vv) {
		cout <<  kv.first << " " << kv.second  << endl;
	}

image.png 发现结果和没写仿函数之前一样,说明仿函数没起效,去看一下仿函数:

其实就是没调仿函数,调一下就可以了:

       struct aa
    {
          bool operator()(const pair<string,int>&kv1,const pair<string,int>& kv2)
    {
        return kv1.second>kv2.second;
    }
    };
把aa传给sort
             sort(vv.begin(),vv.end(),aa());

image.png

提交一下:

image.png

报错了,测试用例太长了,我们可以拿预期结果来和我们的自己的输出做一下对比:

image.png 就拿image.png来看,实际上是sort不够稳定,把相对位置变了。 在算法库里面除了sort之后还有其他排序:

image.png stable_sort是一个稳定的排序,我们可以用它:

      stable_sort(vv.begin(),vv.end(),aa());

image.png

第二种方法: 我们可以自己控制:

image.png

image.png