給定一串數,要求找出滿足sum[l,r]=aim的最長區間[l,r]。
暴力:列舉起點和終點,o(n)。
優化:如果[l1,r]和[l2,r]的區間和相同且l1重新考慮:我們可以固定終點擊取起點,利用字首和sum陣列,sum[i]=∑j=1,i array[j]。當sum[r]=x,我們只需要從1開始找到第乙個sum[i]=x-aim,把[1,i]這段區間挖去,就可以得到以r為最終結束的,長度最長的且滿足區間和為aim的區間。
實現思路:c++可以採用hash,將資料組織為《區間和,結尾元素索引》。預處理時需要向hash中新增元素<0,0>,表示在不累加任何項時,區間和為0出的最小索引為0。【陣列元素從1開始打入】
**:#include
#include
using namespace std;
int sum[505];
int main()
printf("\n");
mappair;
pair.insert(pair(0,0));
for(int i=1;i<=n;i++){
dif=sum[i]-aim;
if(pair.find(dif)!=pair.end()){//存在
maxlen=maxlen空間優化**:
#include
#include
using namespace std;
int main(){
int n,aim,dif,maxlen=-1,sum,pre=0;
mappair;
pair.insert(pair(0,0));
scanf("%d%d",&n,&aim);
for(int i=1;i<=n;i++){
scanf("%d",&sum);
sum+=pre;
pre=sum;
dif=sum-aim;
if(pair.find(dif)!=pair.end()){
maxlen=maxlen變形1:一串數有只有奇數和偶數,求最長的區間滿足奇數與偶數個數相等。
思路:把奇數變1偶數變-1,按照上面的解題思路求aim=0的最長區間即可。
變形2:乙個陣列有0,1,2,求最長的區間滿足1與2個數相等。
思路:0,1不變,2變-1,aim=0。
變形3:乙個數串,可以任意劃分,要求劃分後形成的區間抑或結果為0的區間數最多。
【需要一點dp】:
首先明確幾點抑或的性質:1 . x^x=0 2 . 0^1=1。
像子陣列劃分問題的普遍思路就是固定結尾找符合性質的開頭。
假設當前考慮的數是ai,我們已經求出了a1~ai-1的最多符合性質陣列的個數,分兩種情況:
a . 如果i不是滿足劃分性質的最後乙個區間的最後乙個數,那麼dp[i]=dp[i-1]。
b . 如果i是滿足劃分性質的最後乙個區間的最後乙個數,我們應該找到這個區間的開始j,那麼dp[i]=dp[j-1]+1。
綜上所述,兩者取大即可。
有趣的題目
問題 有100個人圍成乙個圈,從1開始報數,報到14的這個人就要退出。然後其他人重新開始,從1報數,到14退出。問 最後剩下的是100人中的第幾個人?這個題目是自己在做黑馬程式設計師入學測試時遇到的,想了乙個多小時,終於想到了自己的解決方法,網上的過程很繁雜,其實真正的核心 也就4行,上 0102 ...
乙個有趣的題目
看到qq群裡有人發了乙個很有意思的題目 如果 昨天是明天就好了,那麼今天就是周五了,請問句中的今天是週幾?晚上睡覺的時候又想起這個問題,發現這個問題還大有文章,其實問題的關鍵在於上面的綠色背景的如果兩個字,既然是如果,那麼思維就可以完全發散,如果時間可以穿越,明天真的可以穿越到昨天,那麼今天其實就是...
一道有趣的迴圈題目
問題 輸入為 n,求乙個 n n的矩陣,規定沿 45度線遞增,形成乙個 zigzag 陣列 jepg 編碼裡取畫素資料的排列順序 用 c 實現。本人的實現思路 在 程式設計師面試寶典 中有另一種解法 問題的實質是把 0,n 1 中的整數依之字形填入乙個二維陣列。於是考慮按之字形遍歷陣列,遍歷時,方向...