給定陣列arr和整數num,求arr的連續子陣列中滿足:其最大值減去最小值的結果大於num的個數。請實現乙個時間複雜度為o(length(arr))的演算法。
輸入第一行為測試用例個數。每乙個用例有若干行,第一行為陣列,每乙個數用空格隔開,第二行為num。
輸出乙個值。
13 6 4 3 2
2思路:
# 給定陣列arr和整數num,求arr的連續子陣列中滿足:其最大值減去最小值的結果大於num的個數。請實現乙個時間複雜度為o(length(arr))的演算法。
# 蠻力法:在[i,j]子陣列符合後,則其[i,>j]均滿足。時間複雜度為o(n * log2n),不符合
# 滑動視窗:運用滑動視窗,設定視窗左右界,同時,設定最大和最小值的雙端佇列,儲存視窗中的最大最小值的索引。開始左邊界不動,移動右邊界,直到差值大於num,則右邊界不動,統計數量,左邊界進1,繼續移動右邊界。
# 蠻力法
defsub_array_1
(arr, n)
: result =
0for j in
range
(len
(lis)-1
):for k in
range
(j +1,
len(lis)):
if lis[j]
- lis[k]
> n or lis[k]
- lis[j]
> n:
result +=
len(lis)
- k # 當子陣列滿足時,則k比該陣列大的均滿足。
break
return result
# 滑動視窗
defsub_array
(arr, n)
: result =
0 left =
0 right =
0 maxarr =
minarr =
while left <
len(arr)
:while right <
len(arr)
:# 最大值佇列是從左到右遞減,若右端儲存的索引指向的值小於等於右邊界值,則佇列右端出列,直到佇列右端指向值大於邊界值。
# 因為視窗滑動時,左邊值肯定比右邊的值先出,所有當右邊的值比左邊的大時,左邊的值在比較中就沒有意義了。
while
len(maxarr)!=0
and arr[maxarr[-1
]]<= arr[right]
: maxarr.pop(
)# 同理, 最小值佇列從左到右是遞減的
while
len(minarr)!=0
and arr[minarr[-1
]]>= arr[right]
: minarr.pop(
)# 右邊界索引入列
# 左邊界索引入列
if arr[maxarr[0]
]- arr[minarr[0]
]> n:
# 若差值大於num,則右邊界不移動,統計數量,然後左邊界進1
break
right +=
1if maxarr[0]
== left:
# 由於下面要把左邊界進1,因此若最大最小值剛好在左邊界上,則應該出棧
maxarr.pop(0)
if minarr[0]
== left:
minarr.pop(0)
result +=
len(arr)
- right
left +=
1return result
nums =
int(
input()
)for i in
range
(nums)
: lis =
list
(map
(int
,input()
.split())
) n =
int(
input()
)# result = sub_array_1(lis, n)
result = sub_array(lis, n)
(result)
陣列演算法取值
問 對給定的兩個正整數n和m,編號為1 n的n個人圍坐一圈,從1號起連續報數,報道m者出局。剩下的人從當前位置開始從1起報數,報道m者出局.迴圈往復,直至剩下最後乙個人。問出局者順序如何?剩下者的原始編號是幾?剩下者的原始編號是幾?例如,n 6,m 5時,該過程出局者順序為5,4,6,2,3,剩下者...
演算法 子陣列最大累加和
一 題目描述 給定乙個陣列arr,返回陣列的最大累加和。例 arr 1,2,3,5,2,6,1 所有的子陣列中 3,5,2,6 可以累加出最大的和12,所以返回12。二 兩種解法 思路一 暴力法 時間複雜度 o n 2 暴力解法 o n 2 param arr return private stat...
陣列的迴圈取值
燕十八 公益php培訓 學習社群 www.zixue.it arr array 3 梅 2 蘭 5 竹 9 菊 這一次,for迴圈沒有規律可循,再用for迴圈不靈了.引入foreach foreach是怎麼工作的呢?foreach arr as k v echo k,v 停留在最後一次賦值的情況 有...