算法學習筆記:18.拉斯維加斯算法 ——從原理到實戰,涵蓋 LeetCode 與考研 408 例題

在隨機化算法領域,拉斯維加斯(Las Vegas)算法以其獨特的設計思想占據重要地位。與蒙特卡洛(Monte Carlo)算法不同,拉斯維加斯算法總能給出正確的結果,但運行時間具有隨機性 —— 在最壞情況下可能很長,但平均性能往往優于確定性算法。

拉斯維加斯算法核心思路

算法定義與特點

拉斯維加斯算法是一類隨機化算法,其核心特征可概括為:

  • 正確性保障:無論隨機選擇如何,算法最終一定能返回正確結果。
  • 時間隨機性:算法的運行時間取決于隨機選擇的路徑,可能存在極端情況,但平均時間復雜度通常較優。
  • 驗證步驟:算法往往包含 “隨機嘗試 - 驗證結果” 的過程,若驗證失敗則重新嘗試,直至成功。

與其他算法的對比可用下表展示:

算法類型

正確性

時間確定性

典型應用

確定性算法

總是正確

時間確定

冒泡排序、二分查找

蒙特卡洛算法

可能錯誤(有誤差界)

時間確定

素數測試、近似計數

拉斯維加斯算法

總是正確

時間隨機

隨機化快速排序、洗牌

?算法流程

拉斯維加斯算法的典型流程可分為三個階段:

  1. 隨機選擇:根據問題特性生成隨機決策(如隨機選擇 pivot、隨機交換元素)。
  1. 執行操作:基于隨機選擇執行算法核心邏輯(如分區、搜索)。
  1. 驗證結果:檢查當前結果是否滿足問題要求,若滿足則返回,否則回到步驟 1 重新嘗試。

其流程可用以下流程圖表示:

1.3 優勢與適用場景

  • 優勢:無需處理最壞情況的極端輸入(通過隨機性規避),平均性能優異,實現簡單。
  • 適用場景:解決具有 “解存在且可驗證” 特性的問題,如組合優化、搜索、排序等。

LeetCode 例題實戰

例題 1:384. 打亂數組(中等)

題目描述:給你一個整數數組 nums ,設計算法來打亂一個沒有重復元素的數組。打亂后,數組的所有排列應該是等可能的。實現 Solution 類:

  • Solution(int[] nums) 使用整數數組 nums 初始化對象。
  • int[] reset() 重設數組到它的初始狀態并返回。
  • int[] shuffle() 返回數組隨機打亂后的結果。

示例

輸入

["Solution", "shuffle", "reset", "shuffle"]

[[[1, 2, 3]], [], [], []]

輸出

[null, [3, 1, 2], [1, 2, 3], [1, 3, 2]]

解題思路:采用 Fisher-Yates 洗牌算法(拉斯維加斯算法的典型應用),通過隨機交換元素實現等概率打亂:

  1. 遍歷數組,對每個位置 i,隨機選擇 [i, n-1] 范圍內的索引 j。
  1. 交換 nums[i] 與 nums[j],確保每個元素出現在任意位置的概率相等。
  1. 由于每次隨機選擇均能生成有效排列,無需驗證步驟,直接返回結果。

算法圖示:洗牌過程(以 [1,2,3] 為例)

代碼實現

class Solution {private int[] original; // 保存初始數組private int[] shuffled; // 保存打亂后的數組private Random random;public Solution(int[] nums) {original = nums.clone();shuffled = nums.clone();random = new Random();}// 重置數組到初始狀態public int[] reset() {shuffled = original.clone();return shuffled;}// 打亂數組(Fisher-Yates洗牌算法)public int[] shuffle() {int n = shuffled.length;for (int i = 0; i < n; i++) {// 隨機選擇[i, n-1]范圍內的索引int j = i + random.nextInt(n - i);// 交換元素swap(shuffled, i, j);}return shuffled;}private void swap(int[] arr, int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}

復雜度分析

  • 時間復雜度:shuffle() 為 O (n),需遍歷數組并執行 O (1) 交換;reset() 為 O (n),需復制數組。
  • 空間復雜度:O (n),需存儲初始數組和打亂后的數組。
  • 隨機性:通過均勻隨機選擇索引,保證所有排列等概率出現,滿足題目要求。

例題 2:215. 數組中的第 K 個最大元素(中等)

題目描述:給定整數數組 nums 和整數 k,請返回數組中第 k 個最大的元素。請注意,你需要找的是數組排序后的第 k 個最大的元素,而不是第 k 個不同的元素。

示例

輸入: [3,2,1,5,6,4] 和 k = 2

輸出: 5

解題思路:采用隨機化快速選擇算法(拉斯維加斯算法的變種):

  1. 隨機選擇 pivot:避免對有序數組的最壞情況,隨機選擇基準元素。
  1. 分區操作:將數組分為 “小于 pivot”“等于 pivot”“大于 pivot” 三部分。
  1. 驗證與遞歸:根據 pivot 位置判斷是否為目標元素,若不是則遞歸搜索對應子數組。由于 pivot 隨機選擇,平均時間復雜度為 O (n)。

算法圖示:查找 [3,2,1,5,6,4] 中第 2 大元素(5)的過程

代碼實現

import java.util.Random;class Solution {private Random random = new Random();public int findKthLargest(int[] nums, int k) {int n = nums.length;int targetIndex = n - k; // 第k大元素在有序數組中的索引return quickSelect(nums, 0, n - 1, targetIndex);}private int quickSelect(int[] nums, int left, int right, int target) {if (left == right) {return nums[left]; // 基線條件:子數組長度為1}// 隨機選擇pivot并分區int pivotIndex = randomPartition(nums, left, right);// 驗證pivot位置是否為目標if (pivotIndex == target) {return nums[pivotIndex];} else if (pivotIndex < target) {// 目標在右子數組return quickSelect(nums, pivotIndex + 1, right, target);} else {// 目標在左子數組return quickSelect(nums, left, pivotIndex - 1, target);}}// 隨機選擇pivot并執行分區private int randomPartition(int[] nums, int left, int right) {// 隨機選擇[left, right]范圍內的索引作為pivotint pivotPos = left + random.nextInt(right - left + 1);// 將pivot交換到數組末尾swap(nums, pivotPos, right);return partition(nums, left, right);}// 分區操作(類似快速排序)private int partition(int[] nums, int left, int right) {int pivot = nums[right];int i = left - 1; // 小于pivot區域的邊界for (int j = left; j < right; j++) {if (nums[j] <= pivot) {i++;swap(nums, i, j);}}// 將pivot放到最終位置swap(nums, i + 1, right);return i + 1;}private void swap(int[] nums, int i, int j) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}}

復雜度分析

  • 時間復雜度:平均 O (n),最壞 O (n2)(但隨機化后概率極低)。
  • 空間復雜度:O (logn),來自遞歸棧(平均情況)。
  • 隨機性:通過隨機選擇 pivot,避免有序數組導致的 O (n2) 最壞情況,確保平均性能。

考研 408 例題解析

例題 1:概念辨析題(選擇題)

題目:下列關于拉斯維加斯算法的敘述中,正確的是( )。

A. 拉斯維加斯算法可能返回錯誤結果,但錯誤概率可控制

B. 拉斯維加斯算法的運行時間是確定的,與輸入無關

C. 拉斯維加斯算法通過隨機性確保最壞情況下的時間復雜度最優

D. 拉斯維加斯算法適用于 “解存在且可驗證” 的問題

答案:D

解析

  • A 錯誤:拉斯維加斯算法總是返回正確結果,蒙特卡洛算法可能返回錯誤結果。
  • B 錯誤:拉斯維加斯算法的運行時間是隨機的,取決于隨機選擇。
  • C 錯誤:拉斯維加斯算法不能保證最壞情況時間復雜度,但能通過隨機性優化平均復雜度。
  • D 正確:拉斯維加斯算法的 “隨機嘗試 - 驗證” 流程要求解存在且可驗證。

例題 2:算法設計題(應用題)

題目:設計一個拉斯維加斯算法,在有序數組 arr 中查找目標值 target,要求平均時間復雜度優于 O (n)。若數組中存在 target,返回其索引;否則返回 -1。

解題思路

  1. 隨機采樣驗證:利用數組有序性,隨機選擇索引 i 并檢查 arr[i] 與 target 的大小。
  1. 縮小搜索范圍:若 arr[i] < target,則目標只可能在 i+1 右側;若 arr[i] > target,則目標只可能在 i-1 左側。
  1. 遞歸或迭代:重復步驟 1-2 縮小范圍,直至找到目標或范圍為空。若隨機采樣均勻,平均時間復雜度為 O (logn)。

代碼實現

import java.util.Random;public class RandomizedSearch {private Random random = new Random();public int search(int[] arr, int target) {int left = 0;int right = arr.length - 1;while (left <= right) {if (left == right) {return arr[left] == target ? left : -1;}// 隨機選擇范圍內的索引int i = left + random.nextInt(right - left + 1);if (arr[i] == target) {return i; // 找到目標} else if (arr[i] < target) {left = i + 1; // 縮小范圍到右側} else {right = i - 1; // 縮小范圍到左側}}return -1; // 目標不存在}public static void main(String[] args) {int[] arr = {1, 3, 5, 7, 9, 11, 13};RandomizedSearch solver = new RandomizedSearch();System.out.println(solver.search(arr, 7)); // 可能返回3System.out.println(solver.search(arr, 4)); // 返回-1}}

復雜度分析

  • 時間復雜度:平均 O (logn)(隨機采樣大概率落在目標附近,快速縮小范圍),最壞 O (n)(極端隨機選擇)。
  • 空間復雜度:O (1),僅使用常數額外空間。
  • 隨機性:通過均勻隨機選擇索引,避免對特定輸入的最壞情況,優化平均性能。

拉斯維加斯算法的擴展與應用

3.1 實際應用場景

  • 密碼學:生成隨機密鑰(如 RSA 密鑰生成),通過隨機性確保安全性。
  • 游戲開發:隨機地圖生成、卡牌洗牌(如示例 1 的 Fisher-Yates 算法)。
  • 數據庫:隨機采樣查詢優化,通過隨機選擇樣本估算整體統計量。

3.2 與考研 408 的關聯

在考研 408 中,拉斯維加斯算法的考點集中在:

  • 概念辨析:與其他隨機算法的區別(如例題 1)。
  • 算法設計:利用隨機性優化經典算法(如排序、搜索)。
  • 復雜度分析:分析平均時間復雜度,理解隨機性對性能的影響。

總結

拉斯維加斯算法通過 “隨機嘗試 - 驗證結果” 的機制,在保證正確性的同時,利用隨機性優化平均性能,成為解決復雜問題的有力工具。本文通過 LeetCode 例題(打亂數組、查找第 k 大元素)展示了其核心應用,通過考研 408 例題梳理了考點與解題思路。

掌握拉斯維加斯算法不僅能提升算法設計能力,還能深化對隨機性與復雜度關系的理解。在實際應用中,需根據問題特性選擇合適的隨機策略,平衡性能與實現復雜度。

希望本文能夠幫助讀者更深入地理解拉斯維加斯算法,并在實際項目中發揮其優勢。謝謝閱讀!


希望這份博客能夠幫助到你。如果有其他需要修改或添加的地方,請隨時告訴我。

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

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

相關文章

26-計組-指令執行過程

一、指令周期1. 定義與組成定義&#xff1a;CPU取出并執行一條指令所需的全部時間&#xff0c;稱為指令周期。子周期劃分&#xff1a;取指周期&#xff08;必選&#xff09;&#xff1a;從存儲器取指令到指令寄存器&#xff08;IR&#xff09;。間址周期&#xff08;可選&#…

【JMeter】數據驅動測試

文章目錄創建數據文件加載數據文件根據數據文件請求接口、傳遞參數拓展含義&#xff1a;根據數據的數量、內容&#xff0c;自動的決定用例的數據和內容。數據驅動測試用例。步驟&#xff1a; 創建數據文件加載數據文件根據數據文件請求接口、傳遞參數 創建數據文件 Jmeter支…

Springboot實現一個接口加密

首先來看效果這個主要是為了防止篡改請求的。 我們這里采用的是一個AOP的攔截&#xff0c;在有需要這樣的接口上添加了加密處理。 下面是一些功能防篡改HMAC-SHA256 參數簽名密鑰僅客戶端 & 服務器持有防重放秒級時間戳 有效窗口校驗默認允許 5 分鐘防竊聽AES/CBC/PKCS5Pa…

斯坦福 CS336 動手大語言模型 Assignment1 BPE Tokenizer TransformerLM

所有代碼更新至 https://github.com/WangYuHang-cmd/CS336/tree/main/assignment1-basics 作業文件結構: CS336/assignment1-basics/ ├── tests/ # 測試文件目錄 │ ├── adapters.py # 適配器測試 │ ├── conftest.py # pyt…

Spring Cloud Gateway 實戰指南

關鍵詞&#xff1a;微服務、API網關、Spring Cloud Gateway、路由轉發、限流熔斷 ? 文章摘要 隨著互聯網應用規模的不斷擴大&#xff0c;傳統的單體架構逐漸向微服務架構轉型。在微服務架構中&#xff0c;API 網關作為系統的入口點&#xff0c;承擔了諸如請求路由、負載均衡、…

PyTorch自動微分:從基礎到實戰

目錄 1. 自動微分是什么&#xff1f; 1.1 計算圖 1.2 requires_grad 屬性 2. 標量和向量的梯度計算 2.1 標量梯度 2.2 向量梯度 3. 梯度上下文控制 3.1 禁用梯度計算 3.2 累計梯度 4. 梯度下降實戰 4.1 求函數最小值 4.2 線性回歸參數求解 5. 總結 在深度學習中&a…

Spring AI 項目實戰(十六):Spring Boot + AI + 通義萬相圖像生成工具全棧項目實戰(附完整源碼)

系列文章 序號文章名稱1Spring AI 項目實戰(一):Spring AI 核心模塊入門2Spring AI 項目實戰(二):Spring Boot + AI + DeepSeek 深度實戰(附完整源碼)3Spring AI 項目實戰(三):Spring Boot + AI + DeepSeek 打造智能客服系統(附完整源碼)4

從零到一:企業如何組建安全團隊

在這個"黑客滿天飛&#xff0c;漏洞遍地跑"的時代&#xff0c;沒有安全團隊的企業就像裸奔的勇士——雖然很有勇氣&#xff0c;但結局往往很悲慘。 &#x1f4cb; 目錄 為什么要組建安全團隊安全團隊的核心職能團隊架構設計人員配置策略技術體系建設制度流程建立實施…

業務訪問控制-ACL與包過濾

業務訪問控制-ACL與包過濾 ACL的定義及應用場景ACL&#xff08;Access Control List&#xff0c;訪問控制列表&#xff09;是用來實現數據包識別功能的&#xff1b;ACL可以應用于諸多場景&#xff1a; 包過濾功能&#xff1a;對數據包進行放通或過濾操作。NAT&#xff08;Netwo…

穿梭時空的智慧向導:Deepoc具身智能如何賦予導覽機器人“人情味”

穿梭時空的智慧向導&#xff1a;Deepoc具身智能如何賦予導覽機器人“人情味”清晨&#xff0c;當第一縷陽光透過高大的彩繪玻璃窗&#xff0c;灑在博物館光潔的地板上&#xff0c;一位特別的“館員”已悄然“蘇醒”。它沒有制服&#xff0c;卻有著清晰的指引&#xff1b;它無需…

PostgreSQL 查詢庫中所有表占用磁盤大小、表大小

SELECTn.nspname AS schema_name,c.relname AS table_name,-- 1?? 總大小&#xff08;表 toast 索引&#xff09;pg_size_pretty(pg_total_relation_size(c.oid)) AS total_size,-- 2?? 表不包含索引&#xff08;含 TOAST&#xff09;pg_size_pretty(pg_total_relation_s…

日記-生活隨想

最近鼠鼠也是來到上海打拼&#xff08;實習&#xff09;了&#xff0c;那么秉持著來都來了的原則&#xff0c;鼠鼠也是去bw逛了逛&#xff0c;雖說沒票只能在外場看看&#x1f62d;。可惜幾乎沒有多少我非常喜歡的ip&#xff0c;不由感慨現在的二次元圈已經變樣了。雖說我知道內…

串口A和S的含義以及RT的含義

A async 異步S sync 同步RT 收發U A RT 異步U SA RT 同步/異步

spring cloud負載均衡分析之FeignBlockingLoadBalancerClient、BlockingLoadBalancerClient

本文主要分析被 FeignClient 注解的接口類請求過程中負載均衡邏輯&#xff0c;流程分析使用的依賴版本信息如下&#xff1a;<spring-boot.version>3.2.1</spring-boot.version><spring-cloud.version>2023.0.0</spring-cloud.version><com.alibaba.…

ref 和 reactive

文章目錄ref 和 reactive一、差異二、能否替代的場景分析&#xff08;1&#xff09;基本類型數據&#xff08;2&#xff09;對象類型數據&#xff08;3&#xff09;數組類型數據&#xff08;4&#xff09; 需要整體替換的場景三、替代方案與兼容寫法1. 用 reactive 模擬 ref2. …

BatchNorm 與 LayerNorm:原理、實現與應用對比

BatchNorm 與 LayerNorm&#xff1a;原理、實現與應用對比 Batch Normalization (批歸一化) 和 Layer Normalization (層歸一化) 是深度學習中兩種核心的歸一化技術&#xff0c;它們解決了神經網絡訓練中的內部協變量偏移問題&#xff0c;大幅提升了模型訓練的穩定性和收斂速度…

OcsNG基于debian一鍵部署腳本

&#x1f914; 為什么有了GLPI還要部署OCS-NG&#xff1f; 核心問題&#xff1a;數據收集的風險 GLPI直接收集的問題&#xff1a; Agent直接向GLPI報告數據時&#xff0c;任何收集異常都會直接影響資產數據庫網絡問題、Agent故障可能導致重復資產、錯誤數據、資產丟失無法對收集…

001_Claude開發者指南介紹

Claude開發者指南介紹 目錄 Claude簡介Claude 4 模型開始使用核心功能支持資源 Claude簡介 Claude 是由 Anthropic 構建的高性能、可信賴和智能的 AI 平臺。Claude 具備出色的語言、推理、分析和編程能力&#xff0c;可以幫助您解決各種復雜任務。 想要與 Claude 聊天嗎&a…

004_Claude功能特性與API使用

Claude功能特性與API使用 目錄 API 基礎使用核心功能特性高級功能開發工具平臺支持 API 基礎使用 快速開始 通過 Anthropic Console 獲取 API 訪問權限&#xff1a; 在 console.anthropic.com/account/keys 生成 API 密鑰使用 Workbench 在瀏覽器中測試 API 認證方式 H…

ReAct論文解讀(1)—什么是ReAct?

什么是ReAct&#xff1f; 在大語言模型&#xff08;LLM&#xff09;領域中&#xff0c;ReAct 指的是一種結合了推理&#xff08;Reasoning&#xff09; 和行動&#xff08;Acting&#xff09; 的提示方法&#xff0c;全稱是 “ReAct: Synergizing Reasoning and Acting in Lan…