leetCode第十二題和十三題,整數與羅馬數的相互轉換,JavaScript實現

   本博客的做者與csdn裏 Tank_in_the_street的做者是同一做者,轉載文章需寫明出處。

本文章的源碼存放到github上,感興趣的能夠去查看:羅馬數轉整數整數轉羅馬數git

講到整數與羅馬數相互轉換這道題,其實這道題在讀大學的時候作acm也是一道經典的題。爲了容易理解,我先從第十三題羅馬數轉整數這道題開始講起。github

首先第十三題的題目是這樣說的:正則表達式


下面的示例是這樣的:算法


第一眼看其實就能看出這道題的一種解題方法是暴力解題法,該解題是利用正則表達式,解題思路是用一個對象儲存個位上1到9的各類對應的羅馬數字、十位上10到90的各類對應羅馬數字、百上100到900的各類對應的羅馬數字,以此類推。最後經過正則表達式來使輸入的羅馬數變成一個數組,每一個數組的元素則從左往右對應整數的位數,利用儲存羅馬數的對象來得出最後總和的結果。最後結果以下:
數組


雖說暴力解題一時爽,可是顯得代碼十分的冗長。這裏的時間複雜度爲O(n),空間複雜度爲o(n),這裏的空間複雜度爲O(n)是取決於正則返回的數組長度。其實這個暴力方法笨就本在其實對象裏有不少屬性是能夠複用的,根本就不須要寫那麼多個屬性出來。那如何複用呢?咱們知道羅馬數裏1到1000是由下面這幾個字母組成的,分別:函數

I、V、X、L、C、D、Mpost

因此咱們的對象就儲存這六個屬性所對應的值就能夠了。那如何轉換呢?咱們只須要對函數傳過來的字符串進行遍歷,若是當前字符串所對應的值小於下一個字符串所對應的值咱們就能知道當前字符串確定是I,而咱們的算法是判斷當初字符串對應的值是否大於下一個值,是的話就把當前值累加,不是的話減掉當前值,這樣咱們就能夠不用正則表達式和在對象裏存多個屬性就能解得此題:測試


換了新方法後在空間的上的速度快了很多,主要是少用了一個正則表達式。說完羅馬數轉整數,下面難度進階一點,講整數轉羅馬數。既然已經知道了第二種的解法,其實能夠利用第二種解發稍微變通一下就變成了第十二題的解法。咱們能夠把對象裏的羅馬字符屬性名換成整數爲屬性名,屬性值爲羅馬字符串。而後用一個數組儲存對象裏的屬性名,隨後利用雙指針對數組進行遍歷,若是傳過來的參數值大於數組最後一位數,則把當前下標對應的羅馬數拼接到一個字符串遍歷上,而後傳過來的參數減掉比較的數,直到傳過來的參數的值小於1爲止。代碼以下所示:
.net


這裏我認爲有兩個注意點就是爲何對象和上面的對象不同,比上面的對象多了好幾個屬性。這裏主要是簡化循環內的判斷次數,減小空間複雜度。有些代碼若是能執行一次就儘可能執行一次,這樣對空間和時間都有很多的提高。第二點就是我這裏的數組是直接寫值進去的,而不是利用解構和Object.keys來對對象裏的屬性名賦值到數組中,這是由於Object.keys源碼裏執行了兩層for循環,十分的耗時,而數組解構實際上是利用到了slice()函數,也會對內部進行一次遍歷,因此用這種方法的話時間和空間複雜度會很是的高,不太推薦使用。3d

除了這種方法之外,還有一種方法的時間和空間複雜度都爲1,就是暴力解題法,以下:


不過想不明白的是最快160ms的那個代碼是這樣寫的:


其實他用了兩層for循環,時間複雜度妥妥的​,只不過測試的樣本太少,使得他的速度有可能很快。就比如在數據量不多且數據是有序的狀況時,冒泡排序甚至比快速排序還要快。

下一題: leetCode第十四題,最長公共前綴(Longest Common Prefix),JavaScript實現
相關文章
相關標籤/搜索