2025高頻面試算法總結篇【排序】

文章目錄

  • 直接刷題鏈接直達
  • 把數組排成最小的數
  • 刪除有序數組中的重復項
  • 求兩個排序數組的中位數
  • 求一個循環遞增數組的最小值
  • 數組中的逆序對
  • 如何找到一個無序數組的中位數
  • 鏈表排序
  • 從一大段文本中找出TOP K 的高頻詞匯


直接刷題鏈接直達

  • 把一個數組排成最大的數
    • 劍指 Offer 45. 把數組排成最小的數
    • 面試官說需要 通過 補位 思想(普通的compare再sort并不滿意,但補位思想似乎不適用于有重復元素的情況)
  • 如何給一個很大的無序數組去重
    • 26. 刪除排序數組中的重復項(給排序數組去重)
  • 求兩個排序數組的中位數
    • 要求時間復雜度 O(log(m+n))
    • 二分查找,遞歸求整個數組中第K大的元素,完整代碼需要仔細考慮多種邊界條件
    • 4.尋找兩個有序數組的中位數
  • 求一個循環遞增數組的最小值
    • 153. 尋找旋轉排序數組中的最小值 (無重復元素,二分,總有一半有序,注意邊界)
    • 154. 尋找旋轉排序數組中的最小值 II (有重復元素,需要解除相等時的死循環)
  • 數組中的逆序對
    • 歸并排序 && 遞歸的應用
    • 引入輔助數組臨時存放排序好的數據
    • 歸并時指向兩個指針末尾,逐次向前并統計
    • 面試題51. 數組中的逆序對
  • 如何找到一個無序數組的中位數
    • 295. 數據流的中位數 (建立兩個堆,最大堆&最小堆,復雜度分析)
    • 找出一個無序數組的中位數 (快排,縮小Partition區域 / 取一半元素建堆)
  • 鏈表排序
    • 需要 nlog(n) 時間復雜度和常數級空間復雜度
    • 歸并排序的應用(Bottom Up)
    • 找到中點,斷開鏈表(通過快慢兩個指針)
    • 交替雙指針合并
    • 148. 排序鏈表
  • 手寫主流排序算法 & 各種算法的復雜度/穩定性分析
    • 常見問題
      • 手寫快排 / 堆排
      • 快排的復雜度分析(最好/最壞/平均)
      • 堆排中建堆的時間復雜度分析 --> O(n)
        • 堆排序中建堆過程時間復雜度O(n)怎么來的?
        • 為什么建堆的時間復雜度是O(n)?
      • 歸并排序的 Top-Down & Bottom-up 策略
      • 不同排序的穩定性分析
      • 冒泡排序的優化策略(華為)
        • 設置flag位,一輪未交換數據即已完成排序,提前結束
        • 記住本輪最后一次交換發生的位置lastExchange,下次內層循環到此終止即可
    • 排序算法穩定性
    • 排序算法可視化
    • 快排 Wiki / 堆排 Wiki / 歸并排序 Wiki
    • 堆排序(Heapsort) (特別好的講解)
    • 冒泡排序算法及其兩種優化
  • (Top K 問題)給定一個無符號,包含10億個數的數組,如何取出前100大的數
    • 答題思路
      • 首先詢問資源 --> 內存 / 核數 / 單機or多機,如可用多機 --> MapReduce思想
      • 堆排 O(nlogk),可以單機處理海量數據(在內存受限情況下),如果k較小,趨近于 O(n)
        • 建立一個容量為k的大/小頂堆
        • n個元素逐一比較,O(logk) 完成刪除和插入操作
      • 全局排序, O(nlogn) (數據量較小時才可行)
      • 冒泡(k個),O(kn)
      • 快排劃分 O(n), 每次遞歸處理一側的數據,理論上可以理解為每次折半,缺點 --> 存在內存不夠的問題,因為需要一次讀入所有數據
    • 算法必學:經典的 Top K 問題(基本思路篇)
    • 海量數據處理 - 10億個數中找出最大的10000個數(top K問題) (各種資源場景分析,面試前可參考)
    • 最小的K個數(代碼實現,首選堆排)
  • Java自帶的 sort() 方法是如何實現的
    • Array.sort() / Collections.sort()
    • DualPivotQuicksort(雙軸快速排序)
    • Arrays.sort和Collections.sort實現原理解析
    • Collections.sort()和Arrays.sort()排序算法選擇
  • 寫一個快速劃分數據集的算法,要求測試集用新數據,訓練集用老數據
    • 數據格式為 Record(id, timestamp)
    • 函數簽名為 division(ArrayList dataset, double ratio), ratio為(0,1)的劃分比例
    • 要求復雜度為O(n)
  • 從一大段文本中找出TOP K 的高頻詞匯
    • System Design Interview - Top K Problem (Heavy Hitters) (系統設計角度思考本題,如何權衡性能和效率,較為高階)
    • 347. 前K 個高頻元素 (數字頻次代碼實現,建堆,時間復雜度為nlog(k))
    • 692. 前K個高頻單詞 (詞匯頻次代碼實現,思路一致)

把數組排成最小的數

題目:闖關游戲需要破解一組密碼,闖關組給出的有關密碼的線索是:

  • 一個擁有密碼所有元素的非負整數數組 password
  • 密碼是 password 中所有元素拼接后得到的最小的一個數
class Solution {public String crackPassword(int[] password) {String[] strs = new String[password.length];for (int i=0; i < password.length; i++) {strs[i] = password[i] + "";}Arrays.sort(strs, (a, b) -> (a + b).compareTo(b + a));StringBuilder sb = new StringBuilder();for (int i=0; i < password.length; i++) {sb.append(strs[i]);}return sb.isEmpty() ? "0":sb.toString();}
}

刪除有序數組中的重復項

給你一個 非嚴格遞增排列 的數組 nums ,請你 原地 刪除重復出現的元素,使每個元素 只出現一次 ,返回刪除后數組的新長度。元素的 相對順序 應該保持 一致 。然后返回 nums 中唯一元素的個數。

考慮 nums 的唯一元素的數量為 k ,你需要做以下事情確保你的題解可以被通過:

  • 更改數組 nums ,使 nums 的前 k 個元素包含唯一元素,并按照它們最初在 nums 中出現的順序排列。nums 的其余元素與 nums 的大小不重要。
  • 返回 k 。
class Solution {public int removeDuplicates(int[] nums) {if (nums.length == 0) return 0;int k = 0;for (int i = 1; i < nums.length; i++) {if (nums[i] != nums[k]) {nums[++k] = nums[i];}}return k+1;}
}

求兩個排序數組的中位數

題目:
給定兩個大小分別為 m 和 n 的正序(從小到大)數組 nums1 和 nums2。請你找出并返回這兩個正序數組的 中位數 。

  • 算法的時間復雜度應該為 O(log (m+n)) 。

解法:
這道題的關鍵是 二分查找+數組切割,核心思路是 在較短數組上二分查找,然后通過數學推導找到合適的中位數。

  • 設定兩個數組 nums1nums2,保證 nums1 總是最短的數組(這樣可以減少二分查找的搜索范圍)。

  • 對短數組進行二分查找,設 nums1 的長度為 mnums2 的長度為 n,則我們希望找到一個分割點 i(在 nums1 中),同時 j = (m + n + 1) / 2 - i(在 nums2 中)。

  • 確保分割點左側的所有元素 ≤ 右側的所有元素

  • nums1[i-1] <= nums2[j]

  • nums2[j-1] <= nums1[i]

  • 確定中位數

  • 如果 m + n奇數,中位數是左半部分的最大值 max(nums1[i-1], nums2[j-1])

  • 如果 m + n偶數,中位數是 (max(nums1[i-1], nums2[j-1]) + min(nums1[i], nums2[j])) / 2

public double findMedianSortedArrays(int[] nums1, int[] nums2) {// 保證 nums1 是較短的數組if (nums1.length > nums2.length) {return findMedianSortedArrays(nums2, nums1);}int m = nums1.length, n = nums2.length;int left = 0, right = m;int medianPos = (m + n + 1) / 2; // 中位數的位置while (left <= right) {int i = left + (right - left) / 2;  // nums1的分割點int j = medianPos - i;             // nums2的分割點int nums1LeftMax = (i == 0) ? Integer.MIN_VALUE : nums1[i - 1];int nums1RightMin = (i == m) ? Integer.MAX_VALUE : nums1[i];int nums2LeftMax = (j == 0) ? Integer.MIN_VALUE : nums2[j - 1];int nums2RightMin = (j == n) ? Integer.MAX_VALUE : nums2[j];if (nums1LeftMax <= nums2RightMin && nums2LeftMax <= nums1RightMin) {// 找到合適的分割點if ((m + n) % 2 == 0) {return (Math.max(nums1LeftMax, nums2LeftMax) + Math.min(nums1RightMin, nums2RightMin)) / 2.0;} else {return Math.max(nums1LeftMax, nums2LeftMax);}} else if (nums1LeftMax > nums2RightMin) {// 需要向左移動right = i - 1;} else {// 需要向右移動left = i + 1;}}throw new IllegalArgumentException("輸入的數組不符合條件");
}

求一個循環遞增數組的最小值

題目: 已知一個長度為 n 的數組,預先按照升序排列,經由 1 到 n 次 旋轉 后,得到輸入數組。例如,原數組 nums = [0,1,2,4,5,6,7] 在變化后可能得到:

  • 若旋轉 4 次,則可以得到 [4,5,6,7,0,1,2]
  • 若旋轉 7 次,則可以得到 [0,1,2,4,5,6,7]
class Solution {public int findMin(int[] nums) {if (nums == null || nums.length == 0) {throw new IllegalArgumentException("數組不能為空");}int left = 0, right = nums.length - 1;while (left < right) { // 這里是 left < right,而不是 left <= rightint mid = left + (right - left) / 2;if (nums[mid] > nums[right]) {  // 最小值一定在 mid 右側left = mid + 1;} else {// 最小值可能在 mid 或左側right = mid;}}return nums[left]; // 最終 left == right,返回最小值}
}

題目 : 已知一個長度為 n 的數組,預先按照升序排列,經由 1 到 n 次 旋轉 后,得到輸入數組。例如,原數組 nums = [0,1,4,4,5,6,7] 在變化后可能得到:

  • 若旋轉 4 次,則可以得到 [4,5,6,7,0,1,4]
  • 若旋轉 7 次,則可以得到 [0,1,4,4,5,6,7]
class Solution {public int findMin(int[] nums) {if (nums == null || nums.length == 0) {return 0;}int left = 0, right = nums.length - 1;while (left < right) {int mid = left + (right - left) / 2;if (nums[mid] > nums[right]) {left = mid + 1;}else if (nums[mid] < nums[right]) {right = mid;}else {// nums[mid] == nums[right]right--;}}return nums[left];}
}

數組中的逆序對

題目 :在股票交易中,如果前一天的股價高于后一天的股價,則可以認為存在一個「交易逆序對」。請設計一個程序,輸入一段時間內的股票交易記錄 record,返回其中存在的「交易逆序對」總數。

class Solution {public int reversePairs(int[] record) {if (record == null || record.length < 2) return 0;mergeSort(record, 0, record.length - 1);return count;}public void mergeSort(int[] record, int left, int right) {if (left >= right) return;int mid = left + (right-left)/2;mergeSort(record, left, mid);mergeSort(record, mid+1, right);// 合并merge(record, left, mid, right);}int count = 0;public void merge(int[] record, int left, int mid, int right) {int[] temp = new int[right - left +1];int i = left, j = mid+1;int k = 0;while (i <= mid && j <= right) {if (record[i] <= record[j]) {temp[k++] = record[i++];}else {//當左邊數組的大與右邊數組的元素時,就對當前元素以及后面的元素的個數進行統計,//此時這個數就是,逆序數//定義一個計數器,記下每次合并中存在的逆序數。count += mid - i + 1;temp[k++] = record[j++];}}while (i <= mid) temp[k++] = record[i++];while (j <= right) temp[k++] = record[j++];//將新數組中的元素,覆蓋nums舊數組中的元素。//此時數組的元素已經是有序的for(int t =0; t< temp.length;t++){record[left+t] = temp[t];}}
}

如何找到一個無序數組的中位數

中位數是有序整數列表中的中間值。如果列表的大小是偶數,則沒有中間值,中位數是兩個中間值的平均值。

例如 arr = [2,3,4] 的中位數是 3 。
例如 arr = [2,3] 的中位數是 (2 + 3) / 2 = 2.5 。
實現 MedianFinder 類:

MedianFinder() 初始化 MedianFinder 對象。

void addNum(int num) 將數據流中的整數 num 添加到數據結構中。

double findMedian() 返回到目前為止所有元素的中位數。與實際答案相差 10-5 以內的答案將被接受。

class MedianFinder {PriorityQueue<Integer> left;PriorityQueue<Integer> right;public MedianFinder() {left = new PriorityQueue<>((a,b)->b-a); // 最大堆right = new PriorityQueue<>(); // 最小堆}public void addNum(int num) {if (left.size() == right.size()) {right.offer(num);left.offer(right.poll());} else {left.offer(num);right.offer(left.poll());}}public double findMedian() {if (left.size() > right.size()) {return left.peek();}return (left.peek() + right.peek()) / 2.0;}
}

鏈表排序

class Solution {public ListNode sortList(ListNode head) {if (head == null || head.next == null) return head;// 歸并排序ListNode slow = head;ListNode fast = head.next;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;}ListNode newHead = slow.next;slow.next = null;ListNode left = sortList(head);ListNode right = sortList(newHead);ListNode dm = new ListNode(0);ListNode curr = dm;while (left != null && right != null) {if (left.val < right.val) {curr.next = left;left = left.next;curr = curr.next; }else {curr.next = right;right = right.next;curr = curr.next;}}if (left != null) {curr.next = left;}if (right != null) {curr.next = right;}return dm.next;}
}

從一大段文本中找出TOP K 的高頻詞匯

題目: 給你一個整數數組 nums 和一個整數 k ,請你返回其中出現頻率前 k 高的元素。你可以按 任意順序 返回答案。

class Solution {public int[] topKFrequent(int[] nums, int k) {PriorityQueue<int[]> pq = new PriorityQueue<>((a,b)->a[1]-b[1]);Map<Integer, Integer> map = new HashMap<>();for (int i = 0; i < nums.length; i++) {map.put(nums[i], map.getOrDefault(nums[i], 0)+1);}for (int key : map.keySet()) {if (pq.size() < k) {pq.offer(new int[]{key, map.get(key)});}else {if (pq.peek()[1] < map.get(key)) {pq.poll();pq.offer(new int[]{key, map.get(key)});}}}int[] ans = new int[k];for (int i = 0; i < k; i++) {ans[i] = pq.poll()[0];}return ans;}
}

題目: 給定一個單詞列表 words 和一個整數 k ,返回前 k 個出現次數最多的單詞。

返回的答案應該按單詞出現頻率由高到低排序。如果不同的單詞有相同出現頻率, 按字典順序 排序。

class Solution {public List<String> topKFrequent(String[] words, int k) {Map<String, Integer> map = new HashMap<>();for (int i = 0; i < words.length; i++) {map.put(words[i], map.getOrDefault(words[i], 0)+1);}PriorityQueue<String> pq = new PriorityQueue<>((a,b)->{//如果不同的單詞有相同出現頻率, 按字典順序 排序if (map.get(a) == map.get(b)) {return b.compareTo(a);}return map.get(a) - map.get(b);});for (String s:map.keySet()) {pq.offer(s);if (pq.size() > k) {pq.poll();}}String[] ans = new String[k];for (int i = k-1; i >= 0; i--) {ans[i] = pq.poll();}return Arrays.asList(ans);}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/76945.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/76945.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/76945.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

模型壓縮技術從零到一

模型壓縮是深度學習中的重要技術&#xff0c;旨在減小模型尺寸和計算需求&#xff0c;特別適合在移動設備或嵌入式系統上部署。 要點 模型壓縮技術可以顯著減小模型尺寸和計算需求&#xff0c;適合資源受限設備。主要技術包括剪枝、量化、知識蒸餾、低秩分解和輕量級模型設計…

浮點數精度問題

目錄 ieee754標準解決方法 和c語言一樣&#xff0c;所有以ieee754標準的語言都有浮點數精度問題&#xff0c;js也有浮點數精度問題&#xff0c;并且因為是弱類型語言這個問題更嚴重&#xff0c;js的Number類型的數據都被視為浮點數 ieee754標準 js的數字類型就相當于c語言doub…

超大規模數據場景(思路)——面試高頻算法題目

目錄 用4KB內存尋找重復元素 從40個億中產生不存在的整數【位】 如果只讓用10MB空間存儲&#xff1f; 初次遍歷 二次遍歷 用2GB內存在20億個整數中查找出現次數最多的數【分塊】 從億萬個URL中查找問題【分塊 堆】 40億個非負整數中找出現兩次的數【位 不過多個位哈】 …

開源身份和訪問管理方案之keycloak(三)keycloak健康檢查(k8s)

文章目錄 開源身份和訪問管理方案之keycloak&#xff08;三&#xff09;keycloak健康檢查啟用運行狀況檢查 健康檢查使用Kubernetes下健康檢查Dockerfile 中 HEALTHCHECK 指令 健康檢查Docker HEALTHCHECK 和 Kubernetes 探針 開源身份和訪問管理方案之keycloak&#xff08;三&…

FATFS備忘

概述 FATFS文件系統可以掛載SD卡也可以掛載FLASH eMMC等設備 SD卡需要格式化為FAT32模式 塊大小默認即可 移植 SD卡 SD卡扇區大小是 512B SD卡 SDIO模式 可以直接在cubeMX里一鍵設置 先設置好SD卡的設置 這個是選擇支持中文 其余是默認 這個是檢測引腳可以留空 當SD卡插入拔出…

唯美社區源碼AM社區同款源碼

源碼介紹 唯美社區源碼AM社區同款源碼 后端修改application.properties文件內容為你的數據庫 前端修改/config/config.js文件內容為你的后端地址 這兩個文件里要修改的地方我已經用中文標注出來了 截圖 源碼免費下載 唯美社區源碼AM社區同款源碼

現代Web應用的多標簽選擇組件:設計哲學與工程實踐

引言&#xff1a;標簽選擇的重要性與挑戰 在信息爆炸時代&#xff0c;標簽系統已成為內容組織的核心基礎設施。研究表明&#xff1a; 使用標簽系統的平臺用戶留存率提高35% 良好的標簽選擇體驗可提升內容發現效率58% 80%的用戶更傾向于使用提供可視化標簽選擇的應用 本文將…

P3799 小 Y 拼木棒

題目背景 上道題中&#xff0c;小 Y 斬了一地的木棒&#xff0c;現在她想要將木棒拼起來。 題目描述 有 n 根木棒&#xff0c;現在從中選 4 根&#xff0c;想要組成一個正三角形&#xff0c;問有幾種選法&#xff1f; 答案對 1097 取模。 輸入格式 第一行一個整數 n。 第…

Perl 條件語句

Perl 條件語句 引言 在編程中&#xff0c;條件語句是執行分支邏輯的關鍵部分。Perl 作為一種強大的腳本語言&#xff0c;提供了豐富的條件語句&#xff0c;使得開發者能夠根據不同的條件執行不同的代碼塊。本文將深入探討 Perl 中的條件語句&#xff0c;包括 if、unless、els…

流量特征分析-蟻劍流量分析

任務&#xff1a; 木馬的連接密碼是多少 這是分析蟻劍流量&#xff0c;可能是網站的&#xff0c;wireshark過濾http 追蹤流http得到 1就是連接密碼 flag{1}黑客執行的第一個命令是什么 取最后的執行命令。base64解密得 除了id不是蟻劍自帶的命令&#xff0c;其他的都是&…

問題1:Sinal 4在開啟PAC檢查的設備崩潰

? 問題信息 硬件不支持PAC(Pointer Authentication),此類錯誤就是signal 11的錯誤,崩潰信息如下: Build fingerprint: google/sdk_gphone64_arm64/emu64a:16/BP22.250221.010/13193326:userdebug/dev-keys Revision: 0 ABI: arm64 Timestamp: 2025-04-06 11:33:13.923…

FreeRTOS移植筆記:讓操作系統在你的硬件上跑起來

一、為什么需要移植&#xff1f; FreeRTOS就像一套"操作系統積木"&#xff0c;但不同硬件平臺&#xff08;如STM32、ESP32、AVR等&#xff09;的CPU架構和外設差異大&#xff0c;需要針對目標硬件做適配配置。移植工作就是讓FreeRTOS能正確管理你的硬件資源。 二、…

【C++11(下)】—— 我與C++的不解之緣(三十二)

前言 隨著 C11 的引入&#xff0c;現代 C 語言在語法層面上變得更加靈活、簡潔。其中最受歡迎的新特性之一就是 lambda 表達式&#xff08;Lambda Expression&#xff09;&#xff0c;它讓我們可以在函數內部直接定義匿名函數。配合 std::function 包裝器 使用&#xff0c;可以…

JavaScript中的Proxy詳解

1. 什么是Proxy&#xff1f; Proxy是ES6引入的一個強大特性&#xff0c;它允許你創建一個對象的代理&#xff0c;從而可以攔截和自定義該對象的基本操作。Proxy提供了一種機制&#xff0c;可以在對象的基本操作&#xff0c;如屬性查找、賦值、枚舉、函數調用等之前或之后執行自…

【git】VScode修改撤回文件總是出現.lh文件,在 ?所有 Git 項目 中全局忽略特定文件

VScode里面powershell被迫關閉 場景解決辦法 場景 系統&#xff1a;Windows IDE&#xff1a;Visual Studio Code 一旦修改代碼&#xff0c;就算撤回也會顯示 解決辦法 第一步&#xff1a;“C:\Users\用戶名字.gitignore_global”&#xff1a;在該路徑下新建.gitignore_glo…

為什么 LoRA 梯度是建立在全量參數 W 的梯度之上

&#x1f9e0; 首先搞清楚 LoRA 是怎么做微調的 我們原來要訓練的參數矩陣是 W W W&#xff0c;但 LoRA 說&#xff1a; 別動 W&#xff0c;我在它旁邊加一個低秩矩陣 Δ W U V \Delta W UV ΔWUV&#xff0c;只訓練這個部分&#xff01; 也就是說&#xff0c;LoRA 用一個…

Nginx負載均衡時如何為指定ip配置固定服務器

大家在用Nginx做負載均衡時&#xff0c;一般是采用默認的weight權重指定或默認的平均分配實現后端服務器的路由&#xff0c;還有一種做法是通過ip_hash來自動計算進行后端服務器的路由&#xff0c;但最近遇到一個問題&#xff0c;就是希望大部分用戶采用ip_hash自動分配后端服務…

Llama 4 家族:原生多模態 AI 創新的新時代開啟

0 要點總結 Meta發布 Llama 4 系列的首批模型&#xff0c;幫用戶打造更個性化多模態體驗Llama 4 Scout 是有 170 億激活參數、16 個專家模塊的模型&#xff0c;同類中全球最強多模態模型&#xff0c;性能超越以往所有 Llama 系列模型&#xff0c;能在一張 NVIDIA H100 GPU 上運…

【硬件開發技巧】如何通過元器件絲印反查型號

目錄 一、在線數據庫查詢 二、官方資料匹配 三、專業軟件輔助 四、實物比對與場景推斷 五、社區與人工支持 注意事項 一、在線數據庫查詢 專業元器件平臺 Digi-Key、Mouser、ICMaster等平臺支持直接輸入絲印代碼檢索&#xff0c;可獲取芯片型號、技術文檔及替代型號。例如…

【算法/c++】利用中序遍歷和后序遍歷建二叉樹

目錄 題目&#xff1a;樹的遍歷前言題目來源樹的數組存儲基本思想存儲規則示例 建樹算法關鍵思路代碼總代碼 鏈表法 題目&#xff1a;樹的遍歷 前言 如果不是完全二叉樹&#xff0c;使用數組模擬樹&#xff0c;會很浪費空間。 題目來源 本題來自 PTA 天梯賽。 題目鏈接: 樹…