單調棧 雜湊表 768 最多能完成排序的塊 II

2022-08-11 07:54:11 字數 1598 閱讀 4471

2020-05-13 09:38:46

問題描述

這個問題和「最多能完成排序的塊」相似,但給定陣列中的元素可以重複,輸入陣列最大長度為2000,其中的元素最大為10**8。

arr是乙個可能包含重複元素的整數陣列,我們將這個陣列分割成幾個「塊」,並將這些塊分別進行排序。之後再連線起來,使得連線的結果和按公升序排序後的原陣列相同。

我們最多能將陣列分成多少塊?

示例 1:

輸入: arr = [5,4,3,2,1]

輸出: 1

解釋:將陣列分成2塊或者更多塊,都無法得到所需的結果。

例如,分成 [5, 4], [3, 2, 1] 的結果是 [4, 5, 1, 2, 3],這不是有序的陣列。

示例 2:

輸入: arr = [2,1,3,4,4]

輸出: 4

解釋:我們可以把它分成兩塊,例如 [2, 1], [3, 4, 4]。

然而,分成 [2, 1], [3], [4], [4] 可以得到最多的塊數。

注意:arr的長度在[1, 2000]之間。

arr[i]的大小在[0, 10**8]之間。

問題求解

解法一:雜湊

問題規模較小,可以採用雜湊暴力求解。

public int maxchunkstosorted(int arr) 

}return res;

}

解法二:貪心

貪心策略:對當前的數,如果其左側的最大值比右側的最小值要小,那麼可以在當前截斷。

時間複雜度:o(n)

public int maxchunkstosorted(int arr) 

right[n - 1] = arr[n - 1];

for (int i = n - 2; i >= 0; i--)

int res = 1;

for (int i = 0; i < n - 1; i++)

return res;

}

解法三:棧

在棧中儲存range的(min, max),由於我們知道curr_range_min >= prev_range_max這樣劃分才是合理的,如果不符合條件我們就把兩個range進行merge即可。

時間複雜度:o(n)

public int maxchunkstosorted(int arr) ;

while (!stack.isempty() && stack.peek()[1] > curr[0])

stack.push(curr);

}return stack.size();

}

解法四:單調棧

其實就是對上述演算法做了一點優化工作。這裡不再儲存乙個range,只儲存max_value。

public int maxchunkstosorted(int arr) 

}return stack.size();

}

149直線上最多的點數(雜湊表 暴力)

1 題目描述 給定乙個二維平面,平面上有 n 個點,求最多有多少個點在同一條直線上。2 示例 輸入 1,1 2,2 3,3 輸出 3 解釋 o o o 0 1 2 3 4 3 題解 基本思想 hahsmap 暴力,hashmap對重複出現的點計數,暴力三重迴圈,外面兩重迴圈兩點確定直線,最裡面一重迴...

雜湊表 棧 20 有效的括號

給定乙個只包括 的字串,判斷是否有效。左括號必須用相同型別的右括號閉合,左括號必須以正確的順序閉合。首先字串轉換成字元陣列,可以進行for的迴圈。用棧進行判斷,當左括號時,入棧,當右括號時,出棧,如果最後棧非空,返回錯誤。用雜湊陣列進行輔助,增加了 的復用性。同時減少了判斷次數 鍵值對,用key代表...

BZOJ 3956 Count 單調棧 ST表

題目傳送門 挺有思想的一題,但如果弄清楚了思路這題還是挺簡單的。首先我們可以發揮一下自己的腦洞,發現所有的好集對不可能相交。那麼我們可以刷兩遍單調棧,求出每個點作為區間左端點或右端點的次數。對於給定區間,我們先找出區間中最大值所在的位置,顯然所有的好集對最多以這個位置為左端點或右端點,不可能包含這個...