刪數問題的理解與分析
阿新 • • 發佈:2018-11-30
1、實踐題目
刪數問題
2、問題描述
給定n位正整數a,去掉其中任意k(k≤n)個數字後,剩下的數字按原次序排列組成一個新的正整數。對於給定的n位正整數a和正整數 k,設計一個演算法找出剩下數字組成的新數最小的刪數方案。
輸入格式:第 1 行是1 個正整數 a。第 2 行是正整數k。
輸出格式:輸出最小數。
3、演算法描述
本題運用貪心演算法求解。
按照從前往後的順序搜尋,若各位數字遞增,則刪除最後的k位數字;否則刪除第一個遞減區間的首字元,然後回到串首,再重複刪除。
4、具體程式碼
1 #include <iostream> 2 #include <string.h> 3 using namespace std; 4 int main() 5 { 6 char a[101]; // 表示n位正整數a 7 int k; // k表示要刪掉的數字的數量 8 cin>>a>>k; 9 int len,i; // len表示整數a的總位數,i表示第幾位數 10 while(k>0){ // 當需要刪除的數字大於0 時 11 i = 0; // 從第一位的位數開始 12 len = strlen(a); 13 while(i<len&&a[i]<=a[i+1]) 14 // 在保證不超出總位數且前一位數大於後一位數的情況下 15 i++; // 最後迴圈結束,得到一個遞增的前i位數 16 while(i<len){ 17 // 此時若i小於len,說明出現前一位大於後一位的情況 18 a[i]=a[i+1]; // 那麼將後一位小的數字覆蓋前一位大的數字 19 i++; 20 } 21 k--; // 需要刪除的總數字數減少 22 } 23 i=0; 24 len = strlen(a);25 while(a[i]=='0'&&i<len) i++; // 防止出現多個0的情況 26 if(i==len) cout<<'0'; // 防止整數a全被刪除 27 else { 28 for(i=i;i<len;i++) 29 cout<<a[i]; 30 } 31 return 0; 32 }
5、演算法的時間複雜度和空間複雜度
時間複雜度:程式碼的主要演算法部分有兩層迴圈,迴圈的次數是k*n次,其中k表示要刪除的位數,n表示整數a的位數,即時間複雜度為:O(kn)
空間複雜度:演算法中定義了一個char型的陣列,用來儲存整數a的各個位數,即n位數,即空間複雜度為:O(n)
6、心得體會
一開始沒理解好題目,結果導致寫完後的程式碼只有樣例1過了,其他的樣例全部出錯。後來經過和隊友的討論以及借鑑了班級大佬的解題思路,最終順利完成了任務。