給定乙個無序陣列arr,其中元素可正、可負、可0。給定乙個整數k,求arr所有的子陣列中累加和小於或等於k的最長子陣列長度
時間複雜度為o(n),空間複雜度為o(n)
第一行兩個整數n, k。n表示陣列長度,k的定義已在題目描述中給出第二行n個整數表示陣列內的數
輸出乙個整數表示答案
5 -23 -2 -4 0 6
\(1 \leq n \leq 10^5\)思路比較巧妙,建立乙個兩個陣列min_sum和ind,min_sum[i]表示到從輸入陣列末尾到i位置為止的最小子陣列和,ind[i]記錄這個陣列的起始位置索引,注意這裡是從後往前。$-10^9 \leq k \leq 10^9 \(
\)-100 \leq arr_i \leq100 $
參考滑動視窗思想,從左往右對於每個i,求解滿足條件的最大子陣列邊界。
n, k = map(int, input().strip().split(' '))
nums = list(map(int, input().strip().split(' ')))
min_sum = [0]*n
ind = [0]*n
min_sum[-1] = nums[-1]
ind[-1] = n-1
for i in range(n-1)[::-1]:
min_sum[i] = min(min_sum[i+1], 0)+nums[i]
if min_sum[i+1] <= 0:
ind[i] = ind[i+1]
else:
ind[i] = i
#start表示子陣列的開始,end表示結束位置後一位,s表示索引從start到end-1的子陣列和
start = end = s = 0
res = 0
for start in range(n):
end = max(end, start)
# 對於每個start,end不必重新退回到新的start位置。這是因為start是向右移的,要尋找可能存在滿足條件的更大的子陣列的話,end只能在原有的end基礎上右移,因此end不必要重新回到新的start位置。
# start看作左邊界,end看作右邊界+1,當start=end時,代表子陣列為空。
while end < n and s+min_sum[end] <= k:
s += min_sum[end]
end = ind[end]+1
res = max(res, end-start) #記錄最長的子陣列
if end > start: #這裡表示nums[start:end] > k,此時需要將start右移。當start移動到end-1時,此時s=0
s -= nums[start]
print(res)
未排序陣列中累加和小於或等於給定值的最長子陣列長度
來自牛客網左程雲第二課第四題 問題 給定乙個無序陣列 arr,其中元素可正 可負 可 0,給定乙個整數 k。求 arr 所有的子陣列中累加和小於或等於 k 的最長子陣列長度。例如 arr 3,2,4,0,6 k 2,相加和小於或等於 2 的最長子陣列為 所以結果返回 4。要求 時間複雜度 n log...
未排序陣列中累加和小於或等於給定值的最長子陣列長度
題目 未排序陣列中累加和小於或等於給定值的最長子陣列長度 思路 依次求以陣列的每個位置結尾的 累加和小於或等於k的最長子陣列長度,其中最長的那個子陣列長度就是我們要的結果。public class maxlongslengthse sum 0 int pre 0 int len 0 int res ...
未排序陣列中累加和為給定值的最長子陣列系列問題
牛客網左程雲第二課第三題,這是乙個很重要的演算法原型。問題 給定乙個無序陣列 arr,其中元素可正 可負 可 0,給定乙個整數 k。求 arr 所有的子陣列中累加和為 k 的最長子陣列長度。要求 時間複雜度 o n 分析 本題和未排序正數陣列中累加和為給定值的最長子陣列長度這個問題的區別在於,陣列中...