題目描述:
給定乙個整數陣列 nums,返回區間和在 [lower, upper] 之間的個數,包含 lower 和 upper。
區間和 s(i, j) 表示在 nums 中,位置從 i 到 j 的元素之和,包含 i 和 j (i ≤ j)。
說明:
最直觀的演算法複雜度是 o(n2) ,請在此基礎上優化你的演算法。
示例:
輸入: nums = [-2,5,-1], lower = -2, upper = 2,
輸出: 3
解釋: 3個區間分別是: [0,0], [2,2], [0,2],它們表示的和分別為: -2, -1, 2。
方法1:
主要思路:
(1)暴力法,超時;
(2)先計算字首和,再使用o(n2)的時間複雜度,將判斷每一種情形;
class
solution
//計算陣列的字首和
vector<
long
long
>
sum_sub
(nums.
size()
,0);
sum_sub[0]
=nums[0]
;for
(int i=
1;isize()
;++i)
int res=0;
//判斷每一種情形是否符合要求
for(
int i=
0;isize()
;++i)}}
return res;}}
;
方法2:
主要思路:
(1)歸併排序;
(2)前面的思路一致,還是使用字首和;
(3)歸併的過程中,判斷左右範圍可以組成的滿足要求範圍,這裡之所以能夠使用右邊的減去左邊的進行判斷,是因為右邊的在合併之前,一定是在左邊的右邊,既一定能相減,形成乙個區間;
(4)再考慮到左右的各自部分都是有序的,故可以加快判斷有效的範圍;
class
solution
return;}
int mid=left+
(right-left)/2
;//遞迴的進行歸併判斷
merge_find
(sum_sub,tmp,left,mid,lower,upper,res)
;merge_find
(sum_sub,tmp,mid+
1,right,lower,upper,res)
;//找出滿足要求的範圍
int i=left;
int j=mid+1;
int k=mid+1;
while
(i<=mid)
k=j;
//判斷上區間,滿足要求,就統計
while
(k<=right&&sum_sub[k]
-sum_sub[i]
<=upper)
++i;
}//合併左右有序的部分
i=left;
j=mid+1;
k=left;
while
(i<=mid&&j<=right)
else
}//處理沒有合併完的部分
while
(i<=mid)
while
(j<=right)
//賦值到原始陣列
while
(left<=right)
}int
countrangesum
(vector<
int>
& nums,
int lower,
int upper)
//字首和
vector<
long
long
>
sum_sub
(nums.
size()
,0);
sum_sub[0]
=nums[0]
;for
(int i=
1;isize()
;++i)
int res=0;
//統計變數
//輔助陣列
vector<
long
long
>
tmp(nums.
size()
,0);
//歸併排序
merge_find
(sum_sub,tmp,
0,nums.
size()
-1,lower,upper,res)
;return res;}}
;
327 區間和的個數
今天的題目還是看了一陣子 我是鏈結 意思是任意子區間內所有元素的和要在lower和upper之間,可以取等 所以題目中 0,0 2,2 都指向各自位置的元素,0,2 就是從第0個元素 一直加到 第2 個元素 等於 2 所以這就是為什麼輸出是3.class solution sum nums i fo...
327 區間和的個數
給定乙個整數陣列 nums,返回區間和在 lower,upper 之間的個數,包含 lower 和 upper。區間和 s i,j 表示在 nums 中,位置從 i 到 j 的元素之和,包含 i 和 j i j 說明 最直觀的演算法複雜度是 o n2 請在此基礎上優化你的演算法。想到了字首和,同時由...
leetcode327 區間和的個數
給定乙個整數陣列 nums,返回區間和在 lower,upper 之間的個數,包含 lower 和 upper。區間和 s i,j 表示在 nums 中,位置從 i 到 j 的元素之和,包含 i 和 j i j 說明 最直觀的演算法複雜度是 o n2 請在此基礎上優化你的演算法。示例 輸入 nums...