leadcode的Hot100系列--347. 前 K 個高頻元素--hash表+直接選擇排序

来源:https://www.cnblogs.com/payapa/archive/2019/07/12/11173705.html
-Advertisement-
Play Games

這個看著應該是使用堆排序,但我圖了一個簡單,所以就簡單hash表加選擇排序來做了。 使用結構體: 思路: hash表用來存儲每個值對應的頻率,每讀到一個數字,對應的頻率就加1。 然後從表中再把這些數據讀取出來。 先創建兩個長度為k的數組,一個用來記錄頻率,一個用來記錄對應的數值。 讀取數據的時候,使 ...


這個看著應該是使用堆排序,但我圖了一個簡單,所以就簡單hash表加選擇排序來做了。
使用結構體:

typedef struct node
{
    struct node *pNext;
    int value;  // 數值
    int frequency;  // 頻率
}NODE_S;

思路:
hash表用來存儲每個值對應的頻率,每讀到一個數字,對應的頻率就加1。
然後從表中再把這些數據讀取出來。
先創建兩個長度為k的數組,一個用來記錄頻率,一個用來記錄對應的數值。
讀取數據的時候,使用頻率做排序,在排序的時候,也要對應的交換數值的數組。



/**
 * Note: The returned array must be malloced, assume caller calls free().
 */

#define HASH_LEN 10

typedef struct node
{
    struct node *pNext;
    int value;
    int frequency;
}NODE_S;

NODE_S *get_node(NODE_S **pstHead, int num) // 獲取num對應的節點
{
    int n;
    NODE_S *pstTemp;
    if (num<0)
        n = -num;
    else
        n = num;
    pstTemp = pstHead[n%HASH_LEN];
    
    while(NULL != pstTemp)
    {
        if (num == pstTemp->value)
            return pstTemp;
        else
            pstTemp = pstTemp->pNext;
    }
    return pstTemp;
}

void add_node(NODE_S **pstHashHead, int num)   // 添加一個num的節點
{
    NODE_S *pstTemp = NULL;
    NODE_S *pstNode = NULL;
    int i, n;
    
    if (num<0)     // 這裡是防止給的num是負數
        n = -num;
    else
        n = num;
    
    pstTemp = get_node(pstHashHead, num);
    if (NULL == pstTemp)
    {
        pstTemp = (NODE_S *)calloc(1, sizeof(NODE_S));
        if (NULL == pstTemp) return;
        pstTemp->value = num;
        pstTemp->frequency = 1;
        pstNode = pstHashHead[n%HASH_LEN];
        if (NULL == pstNode)
            pstHashHead[n%HASH_LEN] = pstTemp;   // 說明是第一個節點
        else
        {
            while (NULL != pstNode->pNext) // 往後面繼續掛鏈表
            {
                pstNode = pstNode->pNext;
            }
            pstNode->pNext = pstTemp;
        }
    }
    else
    {
        (pstTemp->frequency) ++; // 已經有該節點,則直接頻率加1
    }
    return;
}

void swap(int *frequency, int *value, int i, int k)  // 交換頻率的時候,也要交換對應的數值
{
    int temp = frequency[i];
    frequency[i] = frequency[k];
    frequency[k] = temp;
    temp = value[i];
    value[i] = value[k];
    value[k] = temp;
    return;
}

void selectSort(int *frequency, int *value, int len) // 選擇排序
{
    for(int i=0;i<len-1;i++)
    {
        int min = frequency[len-1-i];
        int local = len-1-i;
        for(int j=0;j<len-1-i;j++)
        {
            if(min > frequency[j])
            {
                min = frequency[j];
                local = j;
            }
        }

        if(local != (len-1-i))
            swap(frequency, value, local, len-1-i);
    }
}

int* topKFrequent(int* nums, int numsSize, int k, int* returnSize){
    NODE_S *pstHashHeadValue[HASH_LEN] = {0};
    NODE_S *pstTemp = NULL;
    int *pTmp, i;
    int *piFrequency = NULL, *piValue = NULL;
    
    for (i=0; i<numsSize; i++)  // 把所有元素都插入到hash表中
    {
        add_node(pstHashHeadValue, nums[i]);
    }
    
    // 這裡生成兩個數組,一個頻率數組,一個數值數組,頻率數組用來排序, 數值數組用來返回
    piFrequency = (int *)calloc(k, sizeof(int));   
    if (NULL == piFrequency) return NULL;
    piValue = (int *)calloc(k, sizeof(int));
    if (NULL == piValue) return NULL;
    
    int count = 0;
    for (i=0; i<HASH_LEN; i++)
    {
        if (NULL != pstHashHeadValue[i])
        {
            NODE_S *pstTemp = pstHashHeadValue[i];
            while (NULL != pstTemp)
            {
                if (count<k)
                {
                    piFrequency[count] = pstTemp->frequency;
                    piValue[count] = pstTemp->value;
                    count ++;
                    if (count == k)
                        selectSort(piFrequency, piValue, k);  // 把數組填滿之後,先做一次排序
                }
                else
                {
                    if (pstTemp->frequency > piFrequency[k-1])   // 只有當該頻率大於當前存儲最小頻率的時候,才需要進行重新排序
                    {
                        piFrequency[k-1] = pstTemp->frequency;
                        piValue[k-1] = pstTemp->value;
                        selectSort(piFrequency, piValue, k);
                    }
                }
                pstTemp = pstTemp->pNext;
            }
        }
    }

    *returnSize = k;
    return piValue;
    
}


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • python零基礎系統學習路線圖,Python語言無所不包,能做非常多的事情,適合各類企業的開發工作,學好Python,前途寬廣! python零基礎系統學習路線圖,Python語言無所不包,能做非常多的事情,適合各類企業的開發工作,學好Python,前途寬廣! python零基礎系統學習路線圖,P ...
  • 看過這篇文章,大廠面試你「雙親委派模型」,硬氣的說一句,你怕啥? 讀該文章姿勢 1. 打開手頭的 IDE,按照文章內容及思路進行代碼跟蹤與思考 2. 手頭沒有 IDE,先收藏,回頭看 (萬一哪次面試問了呢) 3. 需要查看和拷貝代碼,點擊文章末尾出「閱讀原文」 文章內容相對較長,所以添加了目錄,如果 ...
  • 第二種方法:對進行奇數倍n分頻時鐘,首先進行n/2分頻(帶小數,即等於(n-1)/2+0.5),然後再進行二分頻得到。得到占空比為50%的奇數倍分頻。下麵講講進行小數分頻的設計方法。 小數分頻:首先講講如何進行n+0.5分頻,這種分頻需要對輸入時鐘進行操作。基本的設計思想:對於進行n+0.5分頻,首 ...
  • 題目 "P1349 廣義斐波那契數列" 解析 把普通的矩陣乘法求斐波那契數列改一改,隨便一推就出來了 $$\begin{bmatrix}f_2\\f_1 \end{bmatrix}\begin{bmatrix} p&q\\ 1&0\\ \end{bmatrix}^{n 2}=\begin{bmatr ...
  • 當前的運行環境為,PHP7.2.2以 FastCGI 模式運行,預設埠為:9000,Nginx1.15.6 打開nginx配置文件 具體位置根據安裝情況可能會有所差異 在 server{}代碼段里新增以下代碼就可以支持 php 的訪問了 ...
  • 推送的方式: 簡訊推送(第三方) 郵件推送 微信推送 公眾號:認證的公眾號(個人的認證公眾號每天只能發一篇文章),粉絲可以跟公眾號聊天, 未認證公眾號 服務號:企業認證(營業執照),沙箱環境測試 主動給用戶發消息(推送),用戶要接收到推送消息前提是需要關註對應的服務號才行 企業號 微信小程式 公眾號 ...
  • 1、線程的使用步驟 2、第一種定義線程類的方法:繼承java.lang.Thread類 MyThread 文件: public class MyThread extends Thread { private int count=0; @Override public void run() { Sys ...
  • 回車鍵:開始游戲,空格鍵:暫停 / 繼續,方向鍵 或 WSAD 鍵:控制移動方向 下載地址 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...