題目大意:在一維陣列的連續區間找出其總和最大的連續區間。
題目不難,但是很有啟迪的一道題目。
乙個了解時間複雜度題目,用幾種不同的時間複雜度實現,直觀的感受下幾者的速度與效率。
設計乙個演算法時要盡量做到高效。高效之處,就是智慧型之處。
先看看o(n³)的演算法:
//方法maxsum1,maxsum2都是對陣列的所有區間進行遍歷求和,得出最大值
//求a中連續區間的最大和。o(n3)
int maxsum1(const int a,int len)
ret = max(ret,sum);}}
return ret;
}//求a中連續區間的最大和。o(n2)
int maxsum2(const int a,int len)
} return ret;
}//分治法:將陣列平分為左右兩個陣列,則最大和區間定位於二者之一,
//或橫跨兩個陣列,此時則可用遞迴或貪心來得出答案
//求a中連續區間的最大和。o(nlogn)
int maxsum3(const int a,int left,int right)
//將陣列平分
int mid = (left+right)/2;
//情況1:求出橫跨兩個陣列的最大值(一部分在左邊一部分在右邊)
int leftsum = int_min;
int rightsum = int_min;
for(int i=mid,sum=0 ; i>=left ; --i)
for(int i=mid+1,sum=0 ; i<=right ; ++i)
//情況2:最大值位於一方遞迴呼叫
int single = max(maxsum3(a,left,mid),maxsum3(a,mid+1,right));
//返回兩種情況的最大值
return max(single,leftsum+rightsum);
}//動態規劃法
//到a[0]~a[i]的最大值,只能是a[i]本身,或到0~a[i-1]的最大值+a[i],
//所以結束與a[i]的最大值可表示為maxat(i)=max(a[i],maxat(i-1)+a[i])
//所以可以採用迴圈動態規劃來實現這個狀態轉移方程,每步更新這個臨時的最大值sum
//求a中連續區間的最大和。o(n)
int maxsum4(const int a,int len)
return ret;
}
處理資料為10 —>好像看不出什麼差別
處理資料為100 —>好像也看不出什麼差別
處理資料為1000 —>o(n^3)敗下陣來,差別已經出來了,我們再繼續試試
處理資料為10000 —>差距已經拉開了,o(n^3)已經陣亡了
處理資料為100000 —>o(n)依舊不動,nlogn都超過1s了
以上的測試並不完全準確,跟平台機器效能有關,但至少能反映出不同時間複雜度下的處理資料的速度與大小。
綜上,在編寫演算法時,要盡可能的優化它,想方設法完善它。多掌握一些優化技巧,可能會起到事半功倍的效果。
合併時間區間(時間複雜度 O n )
給定乙個按開始時間從小到大排序的時間區間集合,請將重疊的區間合併。時間區間集合用乙個二維陣列表示,二維陣列的每一行表示乙個時間區間 閉區間 其中 0 位置元素表示時間區間開始,1位置元素表示時間區間結束。例 1 輸入 1,3 2,6 8,10 15,18 返回 1,6 8,10 15,18 解釋 時...
時間複雜度和空間複雜度
同一問題可用不同演算法解決,而乙個演算法的質量優劣將影響到演算法乃至程式的效率。演算法分析的目的在於選擇合適演算法和改進演算法。乙個演算法的評價主要從時間複雜度和空間複雜度來考慮。1 時間複雜度 1 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能...
時間複雜度和空間複雜度
1 時間複雜度 1 時間頻度乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時間多,哪個演算法花費的時間少就可以了。並且乙個演算法花費的時間與演算法中語句的執行次數成正比例,哪個演算法中語句執行次數多...