日新刷题 - 692. 前K个高频单词

758 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情

一 描述

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

给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。

返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序

示例 1:

输入: words = ["i", "love", "leetcode", "i", "love", "coding"], k = 2
输出: ["i", "love"]
解析: "i""love" 为出现次数最多的两个单词,均为2次。
    注意,按字母顺序 "i""love" 之前。

示例 2:

输入: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4
输出: ["the", "is", "sunny", "day"]
解析: "the", "is", "sunny""day" 是出现次数最多的四个单词,
    出现次数依次为 4, 3, 21 次。

注意:

  • 1 <= words.length <= 500
  • 1 <= words[i] <= 10
  • words[i] 由小写英文字母组成。
  • k 的取值范围是 [1, 不同 words[i] 的数量]  

进阶:尝试以 O(n log k) 时间复杂度和 O(n) 空间复杂度解决。

二 分析

先对输入字符串数组按照字典序排序,方便后续输出;
然后哈希表求每个单词出现频率;
对出现频率qsort排序;
按照index从原数组抓取输出;

三 答案


/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int cmp(const void * a,const void *b) //qsort库要求参数const
{
    return strcmp(*(char **)a,*(char**)b); //字典序从小到大
    //return strcmp((char *)b,(char *)a) ; //字典序从大到小
}
int comp(const void*a,const void*b)
{
    return *(int*)b - *(int*)a;
}
char ** topKFrequent(char ** words, int wordsSize, int k, int* returnSize){
    *returnSize = 0;
    int* hash = (int*)malloc(sizeof(int) * wordsSize);
    int* hash1 = (int*)malloc(sizeof(int) * wordsSize);
    char** ret = (char**)malloc(k * sizeof(char*));
    
    qsort(words, wordsSize, sizeof(char*), cmp);
    
    int i, j;
    for(i = 0; i < wordsSize; i++) {
        hash[i] = 1;
    }

    for(i = 0; i < wordsSize - 1; i++) {
        if(hash[i] == 0) {
            continue;
        }
        for(j = i + 1; j < wordsSize; j++) {
            if(strcmp(words[j], words[i]) == 0) {
                hash[i]++;
                hash[j] = 0;
            }
        }
    }
    for(i = 0; i < wordsSize; i++) {
        hash1[i] = hash[i];
    }

    qsort(hash1, wordsSize, sizeof(int), comp);
    for(i = 0; i < k; i++) {
        for(j = 0; j < wordsSize; j++) {
            if(hash[j] == hash1[i]) {
                ret[(*returnSize)++] = words[j];
                hash[j] = 0;
                break;
            }
        }
    }
    return ret;
}

四 参考

前K个高频单词(优先队列:大根堆 + 哈希表☀) - 前K个高频单词 - 力扣(LeetCode)