棧與佇列10 可見的山峰對數量

2021-10-01 20:59:39 字數 2300 閱讀 5479

乙個不含有負數的陣列可以代表一圈環形山,每個位置的值代表山的高度。有兩個方向:next方向(逆時針方向),last

方向(順時針)。

山峰a和山峰b相互看見的條件為:

如果a和b是同一座山,認為不能相互看見

如果a和b是不同的山,並且在環中相鄰,認為可以相互看見

如果a和b是不同的山,並且在環中不相鄰,假設兩座山峰高度的最小值為min。如果a通過next或last方向到b的途中沒有高度比min大的山峰,則認為a和b可以相互看見。

給定乙個不含有負數且沒有重複值的陣列arr,請返回有多少對山峰能夠相互看見。

高階問題:給定乙個不含有負數但可能含有重複值的陣列arr,返回有多少對山峰能夠互相看見

如果arr長度為n,在沒有重複值的情況下時間複雜度達到o(1),可能有重複值的情況下時間複雜度達到o(n)。

原問題:如果陣列中所有的數字都不一樣,可見山峰對的數量可以由簡單公式得到:

分析當採用策略,從小找大,即arr=,從2出發,會找到和,但是不去嘗試2能不能看到1,因為這是大找小。

假設當前節點為x,x既不為最大值也不為次大值,此時假設y和z節點分別是x在last和next方向上遇到的第乙個比x大的值,即和

除去最大值和次大值,有i-2個這樣的節點,並且每乙個都能找到2對,除此之外還有次大值看見最大值這一對,所以一共是

高階問題:陣列中的數字可能有重複值,採用的資料結構為單調棧(可以參考之前的單調棧的文章),策略小找大。

棧中儲存的是(value,times),從棧頂到棧底value值依次變大

兩個階段:

1>遍歷階段:

2>清算階段:

單獨清算棧中記錄的階段分為三個小階段

解釋:2*k(每個節點會有兩個山峰對)和1*k(當位於清算階段的第2個小階段時,對外能看見的山峰只有最大山峰,並且只有乙個,因此每個節點只有乙個山峰對)表示,當前節點對外產生的山峰對; c(2,k)表示當前節點內部產生的山峰對

**為高階問題的原始碼

//棧中存放的資料結構

publc class record

}public int getvisiblenum(int arr)

int size=arr.length;

int maxindex=0

//先在換種找到乙個最大值的位置,哪乙個都可以

for(int i=0;istack=new stack();

//先把(最大值,1)這個記錄放入stack中

stack.push(new record(arr[maxindex]));

//從最大值位置的下乙個位置開始沿next方向遍歷

int index=nextindex(maxindex,size);

//用「小找大」的方式統計所有可見山峰對

int res=0;

//遍歷階段開始,當index再次回到maxindex的時候,說明轉了一圈,遍歷階段就結束

while(index!=maxindex)

//當前數字arr[index]要進入棧了,如果和當前棧頂數字一樣就合併

//不一樣就把記錄(arr[index],1)放入棧中

if(stack.peek().value==arr[index])else

index=nextindex(index,size);

} //清算階段

//清算階段第1小階段

while(stack.size()>2)

//清算階段第2小階段

if(stack.size()==2)

//清算階段第3小階段

res+=getinternalsum(stack.pop().times);

return res;

}//如果k==1,返回0;如果k>1,返回c(2,k)

public int getinternalsum(int k)

//環形陣列中當前位置為i,陣列長度為size,返回i的下乙個位置

public int nextindex(int i, int size)

可見的山峰對數量

題目 乙個不含有負數的陣列可以代表一圈環形山,每個位置的值代表山的高度,比如 3,1,2,4,5 4,5,3,1,2 或 1,2,4,5,3 都代表同樣結構的環形山。3 1 2 4 5 3方向叫做next方向 逆時針 3 5 4 2 1 3方向叫做last方向叫做last方向 順時針 山峰a和山峰b...

可見的山峰對數量

可見的山峰對數量 乙個不含有負數陣列可以代表一圈環形山,每個位置的值代表山的高度。比如,或都代表同樣結構的環形山。3 1 2 4 5 3 方向叫作 next 方向 逆時針 3 5 4 2 1 3 方向叫作 last 方向 順時針 山峰 a 和 山峰 b 能夠相互看見的條件為 如果 a 和 b 是同一...

leetcode 探索 佇列與棧 島嶼數量

給你乙個由 1 陸地 和 0 水 組成的的二維網格,請你計算網格中島嶼的數量。島嶼總是被水包圍,並且每座島嶼只能由水平方向或豎直方向上相鄰的陸地連線形成。此外,你可以假設該網格的四條邊均被水包圍。示例 1 輸入 11110 11010 11000 00000 輸出 1 示例 2 輸入 11000 1...