雙堆實現任意刪除 天際線掃瞄

2021-10-10 17:11:14 字數 2563 閱讀 9780

堆其結構為完全二叉樹,物理儲存採取陣列,乙個點i 其孩子節點為 2i+1 2i+2 堆的操作包含top() pop() push()

並且這些操作都是基於堆的頂部進行,其通常呼叫down下沉操作和up上浮操作。

堆不支援任意節點的刪除(意味著節點之間順序打亂)。通常可以基於雙堆實現邏輯刪除。

class

my_heap

void

erase

(int _v)

//任意節點刪除

inttop()

//獲取最大值

//將待刪除全部刪除後 q1堆頂即為真正的最大值

if(q1.

empty()

)return0;

else

return q1.

top();

}bool

empty()

//當前堆是否為空

當需要刪除任意元素val時,將val壓入q2。下一次的實際堆q1的top() pop()操作時:

將q1堆頂和q2堆頂相等的元素刪除(pop) 同時由於兩邊堆頂總是存放最大值=》確保刪除的正確性

題目描述給定乙個n \times 3n×3的矩陣matrix,對於每乙個長度為3的小陣列arr,都表示乙個大樓的三個資料。arr[0]表示大樓的左邊界,arr[1]表示大樓的右邊界,arr[2]表示大樓的高度(一定大於0)。每座大樓的地基都在x軸上,大樓之間可能會有重疊,請返回整體的輪廓線陣列

[要求]

時間複雜度為o(n log n)

輸入:

82 5 6

1 7 4

4 6 7

3 6 5

10 13 2

9 11 3

12 14 4

10 12 5

輸出:

直觀思路初始化乙個x軸,大小為arr[50000] 其中50000所有樓分布最大範圍

每遇到乙個樓 left=>right 開始遍歷x軸上left=>right的區間

研究: height>x.height 如果是,更新x.height 即更新對應位置最高點

該思路複雜度很高為 o(n*n) 即每一棟樓需要一次遍歷,而且最關鍵是每乙個座標的遍歷

優化思路

不再研究每乙個座標點,而是研究關鍵點:

每一棟樓包含兩個關鍵點:即左邊點、右邊點

初始化:

將所有大樓的關鍵點,按照下標x排序。

維護乙個最大堆,堆頂存放高度最高的關鍵點。

採取index、height標記當前研究區間的起點和高度。

從左往右掃瞄過程:

①每遇到乙個左關鍵點,加入heap,分析heap.top()>height? 即當前大樓加入使得天際線變高:

如果變高,那麼輸出前一段區間和高度。

②每遇到乙個右關鍵點,意味者一棟大樓結束,那麼需要從heap中刪除該左關鍵點的高度,刪除後,研究

heap.top()由此可以得出,掃瞄過程的幾個特點,其類似於人真實的記錄樓層高度的過程:

struct node};

bool

static

cmp1

(node a,node b)

intmain()

sort

(node_arr.

begin()

,node_arr.

end(

),cmp1)

;//初始化兩個最大堆 以支援任意節點的刪除

my_heap skyline;

int len=node_arr.

size()

;int height=0;

//當前樓最大高度

int index=0;

//當前最大高度的左起點

for(

int i=

0;i)//開始從左往右掃瞄關鍵點

}else

//遇到右邊關鍵點}}

}

易錯點:

SWFLoader實現任意縮放

有的時候我們想通過swfloader來載入乙個外部的swf檔案,但是頭疼的問題就是當我們把瀏覽器放大放小的時候載入的swf大小並不發生變化。現在說一下swfloader他預設 則會縮放內容以適應swfloader控制項並且保持載入內容的高寬比例。但是我們有時候需要通過swfloader縮放來適應載入...

實現任意進製轉化

問題描述 實現十進位制轉num換成r進製數,num和r從鍵盤讀入 假定num為int且 32767 num 32767,r為int且2 r 16 程式設計可用素材 printf input the num,r printf output n 程式的執行效果應類似地如圖1和圖2所示,圖1中的4095,...

Leecode Pow x, n 實現任意次方函式

pow x,n implement pow x,n 實現任意次方函式,注意 1 n可以為正和負 2 x可以為正和負 下面使用二分法求解,不過因為兩個的子解是一樣的,所以可以只求一邊解就可以了,這就是最典型的減治法了。下面給出二分,三分,五分的求解程式 double pow double x,int ...