1、題目要求
我們把只包含因子2、3、5的數稱作醜數,求按從小到大的順序的第1500個醜數。例如,6、8都是醜數,但14不是,因為它包含因子7.習慣上我們把1當做第乙個醜數。
2、題目分析
方法一:
首先,我們再來仔細分析一下醜數的概念,因為2,3,5是醜數的因子,那麼就可以說明任意乙個醜數對其中乙個因子求余為0。醜數只能被2,3,5整除,也就是說,如果能被5整除,就除以連續5,如果最後得到的是1,那麼這個數就是醜數。
因此,我們可以寫出下面的函式來判斷乙個數是不是醜數
bool
isugly
(int number)
intgetuglynumber
(int index)
}return number;
}
但是這種方法最大的問題就是每個整數都要計算,即使乙個整數不是醜數,我們還是要對其進行除法和求餘操作。因此這種演算法的時間效率不是很高。
方法二:建立陣列儲存已經找到的醜數,用空間換時間的解法
基於上述演算法的弊端,我們要找到一種只計算醜數的方法,而不在非醜數的整數上花費時間。我們可以建立乙個陣列,裡面的數字是排好序的醜數。每個醜數都是前面的醜數乘以2、3或者5得到的。我們把已有最大的醜數記做m,接下來分析如何生成下乙個醜數,該醜數肯定是前面某乙個醜數乘以2、3或者5的結果,所以我們把已有的醜數乘以2得到m2,把已有的醜數乘以3得到m3,把已有的醜數乘以5得到m5。最後比較三個數的最小值。**實現如下:
int
min(
int number1,
int number2,
int number3)
intgetuglynumber
(int index)
int ugly = puglynumber[nextuglyindex -1]
;delete
puglynumber;
return ugly;
}
1、題目要求在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對,輸入乙個陣列,求出這個陣列中的逆序對的總數。例如:在陣列中,一共存在5個逆序對,分別是(7,6)、(7,5)、(7,4)、(6,4)和(5,4)。
2、題目分析
方法一:
對這道題最直觀的解法可能就是順序掃瞄整個陣列,每掃瞄到乙個數字,逐個比較該數字後面的數字的大小,求出這個陣列中的逆序對。但是這種方法的效率不高,時間複雜度可達o(n^2)
方法二:一種以空間換時間的解法
具體的分析我們還是以陣列來進行分析。我們先考慮比較兩個相鄰的數字。總的概括來說就是乙個先分解再組合的過程,類似於歸併排序。如下圖所示:
過程1和過程2就是乙個不斷分解的過程,當分解成只有乙個元素的時候就要開始合併了,合併的過程是進行排序的合併,並且要統計其中的逆序對。
現在最關鍵的就是過程4合併、排序並統計逆序對的過程。這時,我們需要定義三個指標,p1,p2和p3,其中p1和p2分別指向兩個陣列的末尾,p3指向輔助陣列的末尾。如下圖a所示。每次比較兩個指標指向的數字,如果p1指向的數字大於p2指向的數字,則構成了逆序對,並且逆序對的數目為第二個子陣列中剩餘數字的個數(本題中為2)。接下來把p1,p2所指的數字中較大的數字從後往前複製到下面的輔助陣列中,然後對應的指標往前挪動一位,如面b圖所示。然後再進行上述的比較過程,此時由於p1指向的數字小於p2所指向的數字,所以是不構成逆序對的,但是同樣將p1,p2所指的數字中較大的數字從後往前複製到下面的輔助陣列中,然後對應的指標往前挪動一位,如面c圖所示
有了上述詳細的討論,我們就可以總結出統計逆序對的過程:先把陣列分隔成子陣列,統計出子陣列內部的逆序對數目,然後再統計出兩個相鄰子陣列之間的逆序對的陣列。在統計逆序對的過程中,還需要對陣列進行排序。所以寫出**實現如下:
int
inversepairscore
(int
* data,
int* copy,
int start,
int end)
int length =
(end - start)/2
;int left =
inversepairscore
(data, copy, start, start + length)
;int right =
inversepairscore
(data, copy, start + length, end)
;//i初始化為前半段的最後乙個數字的下標
int i = start + length;
//jj初始化為後半段的最後乙個數字的下標
int j = end;
int indexcopy = end;
int count =0;
while
(i >= start && j >= start + length +1)
else
}for
(; i >= start; i--
) copy[indexcopy--
]= data[i]
;for
(; j >= start + length +
1; j--
) copy[indexcopy--
]= data[j]
;return count + left + right;
}int
inversepairs
(int
* data,
int length)
以空間換時間經典演算法
以前看過一篇文章 優化c 常用的幾招 作者提到的第一招就是 以空間換時間 還舉了乙個例子,由於比較經典,引用一下 電腦程式中最大的矛盾是空間和時間的矛盾,那麼,從這個角度出發逆向思維來考慮程式的效率問題,我們就有了解決問題的第1招 以空間換時間。比如說字串的賦值 方法a 通常的辦法 define l...
以空間換時間的計數排序
我們前面學習的插入 歸併 堆和快速排序都是比較排序,即在排序的最終結果中,各元素的次序依賴於它們之間的比較。我們說過比較排序有時間下界,即nlgn,如果我們需要乙個時間複雜度為o n 的排序演算法,要怎麼辦?計數排序就是比較好的選擇。計數排序的基本思想是 對每乙個輸入的元素x,確定小於x的元素個數。...
以時間換空間,聯合主鍵 舉例
在建立資料庫是,以空間換時間應該怎麼理解呢,舉例 建設你要建立乙個商品的資料庫,肯定要有乙個商品表goods,這個商品有喝多宣傳,那肯定還要有乙個表goods image表,而且乙個 商品可以對應很多,所以是一對多的關係 但是這個商品有乙個主宣傳,那麼如果將主 宣傳也新增到goods image的表...