剑指offer 算法 (时间效率)
數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度為9的數組{1,2,3,2,2,2,5,4,2}。由于數字2在數組中出現了5次,超過數組長度的一半,因此輸出2。
解析:保存數組首個數字,計數值置一,然后遍歷整個數組。遇到相同的數組,計數值加一,遇到不同的數字,計數值減一,當計數值減到零時,用當前數組數字替換保存的數字,再繼續進行比較,以此類推,比較直到數組尾。因為重復出現的數字次數超過數組長度一半,因此結果保存的數字即為所求數組數字
題目描述
輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。
解析:以最小堆的方式調整數組排序,此時,樹根節點即為最小值,每求出一個最小值,下次進行排序時去掉樹根節點進行排序,以此類推,依次求出每一次的最小值
class Solution { public:vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {vector<int> res;if(k > input.size()) return res;for(int i = 0; i < k; i++){heapSort(input,i,input.size());res.push_back(input[i]);}return res;}void heapSort(vector<int> &input, int root, int end){//堆排序 for(int j = end - 1; j > root; j--){int parent = (j - 1 - root) / 2 + root;//parent=(j-1)/2if(input[parent] > input[j]){//交換input[parent] += input[j];input[j] = input[parent] - input[j];input[parent] -= input[j];}}} };題目描述HZ偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會后,他又發話了:在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,并期望旁邊的正數會彌補它呢?例如:{6,-3,-2,7,-15,1,2,2},連續子向量的最大和為8(從第0個開始,到第3個為止)。你會不會被他忽悠住?
解析:累加:若累加和小于當前值,說明應從當前值開始累加;每次累加時比較替換最大累加值 class Solution { public:int FindGreatestSumOfSubArray(vector<int> array) {int length=array.size();if(length > 0){int sum=array[0];int max=array[0];for(int i=1;i<length;i++){sum+=array[i];if(sum<array[i])sum=array[i];if(max<sum)max=sum;}return max;}return 0;} };
題目描述
求出1~13的整數中1出現的次數,并算出100~1300的整數中1出現的次數?為此他特別數了一下1~13中包含1的數字有1、10、11、12、13因此共出現6次,但是對于后面問題他就沒轍了。ACMer希望你們幫幫他,并把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數。
解析:
方法一:末尾為1時對10取余等于1,因此,對每個數依次取余并除十再取余,直到為零。累加得結果
方法二:
同理分析4位數,5位數。。。。。
設N = abcde ,其中abcde分別為十進制中各位上的數字。
如果要計算百位上1出現的次數,它要受到3方面的影響:百位上的數字,百位一下(低位)上的數字,百位一上(高位)上的數字。
如果百位上數字為0,百位上可能出現1的次數由更高位決定。比如:12013,則可以知道百位出現1的情況可能是:100~199,1100~1199,2100~2199,,.........,11100~11199,一共1200個。可以看出是由更高位數字(12)決定,并且等于更高位數字(12)乘以 當前位數(100)。
如果百位上數字為1,百位上可能出現1的次數不僅受更高位影響還受低位影響。比如:12113,則可以知道百位受高位影響出現的情況是:100~199,1100~1199,2100~2199,,.........,11100~11199,一共1200個。和上面情況一樣,并且等于更高位數字(12)乘以 當前位數(100)。但同時它還受低位影響,百位出現1的情況是:12100~12113,一共114個,等于低位數字(113)+1。
如果百位上數字大于1(2~9),則百位上出現1的情況僅由更高位決定,比如12213,則百位出現1的情況是:100~199,1100~1199,2100~2199,...........,11100~11199,12100~12199,一共有1300個,并且等于更高位數字+1(12+1)乘以當前位數(100)。 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??綜合以上三種情況,當百位對應0或>=2時,有(a+8)/10次包含所有100個點,還有當百位為1(a%10==1),需要增加局部點b+1
?之所以補8,是因為當百位為0,則a/10==(a+8)/10,當百位>=2,補8會產生進位位,效果等同于(a/10+1)
class Solution { public:int NumberOf1Between1AndN_Solution(int n){int sum=0;for(int i=1;i<=n;i++)sum+=count(i);return sum;}int count(int n){int cnt=0;while(n){if(n%10==1)cnt++;n=n/10;}return cnt;} };
class Solution { public:int NumberOf1Between1AndN_Solution(int n){int cnt = 0;int i = 1;for(i = 1;i <= n;i = i*10){int a = n / i , b = n % i ;cnt = cnt + ( a + 8 ) / 10 * i + ( a % 10 == 1 ) * ( b + 1 ) ;}return cnt;} };
題目描述
輸入一個正整數數組,把數組里所有數字拼接起來排成一個數,打印能拼接出的所有數字中最小的一個。例如輸入數組{3,32,321},則打印出這三個數字能排成的最小數字為321323。
解析:把數組每個數字轉換為字符串,比較后重新排序
總結
以上是生活随笔為你收集整理的剑指offer 算法 (时间效率)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 剑指offer 算法 (分解让复杂问题简
- 下一篇: C++ 排序函数 sort(),qsor