Java利用跳躍表解決雙重隊列問題詳解
一 問題描述
銀行的每個客戶都有一個正整數(shù)標(biāo)識 K,到銀行請求服務(wù)時將收到一個正整數(shù)的優(yōu)先級 P 。銀行經(jīng)理提議打破傳統(tǒng),在某些時候調(diào)用優(yōu)先級最低的客戶,而不是優(yōu)先級最高的客戶。系統(tǒng)將收到以下類型的請求:
① 0,系統(tǒng)需要停止服務(wù)。
② 1 K P,將客戶 K 及優(yōu)先級 P 添加到等待列表中。
③ 2,為優(yōu)先級最高的客戶提供服務(wù),并將其從等待名單中刪除。
④ 3,為優(yōu)先級最低的客戶提供服務(wù),并將其從等待名單中刪除。
二 輸入
輸入的每一行都包含一個請求,只有最后一行包含停止請求(代碼0)。假設(shè)有請求在列表中包含新客戶(代碼1),在同一客戶的列表中沒有其他請求或有相同的優(yōu)先級,標(biāo)識符 K 總是小于10^6 ,優(yōu)先級 P 總是小于10^7 。一個客戶可以多次到銀行請求服務(wù),但是每次都獲得不同的優(yōu)先級。
三 輸出
對代碼為 2 或 3 的每個請求都單行輸出所服務(wù)客戶的標(biāo)識。若請求在等待列表為空時到達,則輸出 0。
四 輸入和輸出樣例
1 輸入樣例
2
1 20 14
1 30 3
2
1 10 99
3
2
2
0
2 輸出樣例
0
20
30
10
0
五 分析和設(shè)計
本問題包括插入、刪除優(yōu)先級最高元素和刪除優(yōu)先級最低元素等3種操作,可以使用跳躍表解決。
六 代碼
package com.platform.modules.alg.alglib.poj3481; import java.util.Random; public class Poj3481D { private int INF = 0x7fffffff; private int MAX_LEVEL = 16; public String output = ""; public String cal(String input) { Init(); int op, num, val; String[] line = input.split("\n"); int count = 0; while (true) { String commad[] = line[count++].split(" "); op = Integer.parseInt(commad[0]); if (op == 1) { num = Integer.parseInt(commad[1]); val = Integer.parseInt(commad[2]); Insert(num, val); } else if (op == 0) { return output; } else if (op == 2) Delete(true); else Delete(false); } } class Node { int num, val; Node forward[] = new Node[MAX_LEVEL]; } public Poj3481D() { for (int i = 0; i < updata.length; i++) { updata[i] = new Node(); } } Node head; Node updata[] = new Node[MAX_LEVEL]; int level, max_k, min_k; void Init() { level = 0; max_k = -INF; min_k = INF; head = new Node(); for (int i = 0; i < MAX_LEVEL; i++) head.forward[i] = null; head.val = -INF; } // 按規(guī)則選擇數(shù)據(jù)應(yīng)該在哪層插入 int RandomLevel() { int lay = 0; while (new Random().nextInt(100) % 2 == 0 && lay < MAX_LEVEL - 1) lay++; return lay; } // 查找最接近val的元素 Node Find(int val) { Node p = head; for (int i = level; i >= 0; i--) { while (p.forward[i] != null && p.forward[i].val < val) p = p.forward[i]; updata[i] = p; // 記錄搜索過程中各級走過的最大節(jié)點位置 } return p; } void Insert(int num, int val) { if (val > max_k) max_k = val; if (val < min_k) min_k = val; Node s; int lay = RandomLevel(); if (lay > level) // 要插入的層 > 現(xiàn)有層數(shù) level = lay; Find(val); //查詢 s = new Node(); // 創(chuàng)建一個新節(jié)點 s.num = num; s.val = val; for (int i = 0; i < MAX_LEVEL; i++) s.forward[i] = null; for (int i = 0; i <= lay; i++) { // 插入操作 s.forward[i] = updata[i].forward[i]; updata[i].forward[i] = s; } } // flag=false 表示刪除最小值,true 表示刪除最大值 void Delete(boolean flag) { int d; if (flag) d = max_k; else d = min_k; if (d == -INF || d == INF) { // 說明還沒有插入元素 output += "0\n"; return; } Node p = Find(d); if (p.forward[0] != null && p.forward[0].val == d) { output += String.format("%d\n", p.forward[0].num); if (p.val == -INF && p.forward[0].forward[0] == null) // 刪除唯一節(jié)點 { max_k = -INF; min_k = INF; } else { if (flag) max_k = p.val; else min_k = p.forward[0].forward[0].val; } for (int i = level; i >= 0; i--) { // 刪除操作 if (updata[i].forward[i] != null && updata[i].forward[i].val == d) updata[i].forward[i] = updata[i].forward[i].forward[i]; } } } }
七 測試
到此這篇關(guān)于Java利用跳躍表解決雙重隊列問題詳解的文章就介紹到這了,更多相關(guān)Java跳躍表解決雙重隊列內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IDEA中使用Docker Compose容器編排的實現(xiàn)
這篇文章主要介紹了IDEA中使用Docker Compose容器編排的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07Skywalking改成適配阿里云等帶Http?Basic的Elasticsearch服務(wù)
這篇文章主要介紹了改造Skywalking支持阿里云等帶Http?Basic的Elasticsearch服務(wù)2022-02-02SpringBoot 文件或圖片上傳與下載功能的實現(xiàn)
這篇文章主要介紹了SpringBoot 文件或圖片上傳與下載功能的實現(xiàn),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-02-02解決SpringBoot使用@Value獲取不到y(tǒng)aml中配置值的問題
在最近的開發(fā)中遇到一個問題,使用@Value獲取yml文件中配置的屬性時始終獲取不到值,所以本文給大家詳細(xì)介紹了SpringBoot使用@Value獲取不到y(tǒng)aml中值的問題分析及解決方法,需要的朋友可以參考下2024-01-01java配置變量的解釋,搬運他人優(yōu)質(zhì)評論(推薦)
這篇文章主要介紹了java配置變量,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Struts2源碼分析之ParametersInterceptor攔截器
這篇文章主要介紹了Struts2源碼分析之ParametersInterceptor攔截器,ParametersInterceptor攔截器其主要功能是把ActionContext中的請求參數(shù)設(shè)置到ValueStack中,,需要的朋友可以參考下2019-06-06