逆序;及巧妙變換分析
今日面試題:逆序
一個整數,可以表示為二進位制的形式,請給出儘可能多的方法對二進位制進行逆序操作。 例如:10000110 11011000的逆序為 00011011 01100001
=====================================
巧妙變換分析
原題
輸入陣列[a1,a2,...,an,b1,b2,...,bn],建構函式,使得輸出為,[a1,b1,a2,b2,...,an,bn],注意:方法要是in-place的。
分析
這個題目,並不是一個有難度的題目。描述很簡單,儘管要求了in-place的方法,解決的方法還是很多的。在下面介紹方法的時候,我們都以[a1,a2,a3,a4,b1,b2,b3,b4]為例。
in-place
我們經常在面試題目中看到這個詞,這個到底是什麼意思呢?我們看看wiki中的說法:In computer science, an in-place algorithm (or in Latin in situ) is an algorithm which transforms input using a data structure with a small, constant amount of extra storage space. 所以,如果這個題目的解法,需要O(n)的空間。則不是in-place的演算法,in-place對應的是out-of-place。
最容易想到的方法
通過觀察輸入輸出的格式,直接通過將b1進行交換,直至目標的位置,其他元素也如此操作。直到完成變換。如下的過程:
a1 | a2 | a3 | a4 | b1 | b2 | b3 | b4 |
確定b1的位置,b1要和前面3個元素依次交換。
a1 | b1 | a2 | a3 | a4 | b2 | b3 | b4 |
確定b2的位置,b2要和前面的2個元素一次交換,同樣為了保證in-place。注意交換次數少了一次。
a1 | b1 | a2 | b2 | a3 | a4 | b3 | b4 |
依次確定b3和b4的位置,b4是最後的元素,不需進行交換,b3需要交換一次。
a1 | b1 | a2 | b2 | a3 | b3 | a4 | b4 |
通過上面的分析,則整體的交換次數,3+2+1=6,不失一般性(n-1)+…+1,時間複雜度O(n^2)。
特別的方法
同樣針對上面的例子: 第一步:交換最中間的一對元素,得到
a1 | a2 | a3 | b1 | a4 | b2 | b3 | b4 |
第二步:交換最中間的兩對元素,得到
a1 | a2 | b1 | a3 | b2 | a4 | b3 | b4 |
第三步:交換最中間的三對元素,得到
a1 | b1 | a2 | b2 | a3 | b3 | a4 | b4 |
完畢,得到結果。
在上面的交換中,交換的次數分別為1,2,3,推而廣之,1,…,n-1,則時間複雜度仍舊是O(n^2)的。
in-place的O(n)方法
這個問題,是存在O(n)時間複雜度的in-place演算法的。但是,並不是很好理解。這裡引用@xiaxia同學的說明,他發表在水木上。希望同學們能夠理解:
首先,對2n=3^k - 1的情況下,k是整數。這時候可以通過幾個cyclic shift解決。
每個cycle的起始位置是3^i, i=0,1,...,k-1. cycle裡面元素下標的符合這樣的模式(3^i×2^j) mod (2n+1) 舉例說明:k=2時,2n=8.
假設一個數列是[1,2,3,4,5,6,7,8]
那麼這幾個cycle是
i=0, 3^i=1, [1,2,4,8,16,32] mod 9 = [1,2,4,8,7,5]
i=1, 3^i=3, [3,6] mod 9 = [3,6]
顯然這些cycle都是閉合的,比如對[1,2,4,8,7,5], 5×2 mod 9 = 1, 對[3,6] 6×2 mod 9 = 3
下面做這兩個cyclic shift
做完第一個後:
[1,2,3,4,5,6,7,8] -> [5,1,3,2,7,6,8,4]
做完第二個後:
[5,1,3,2,7,6,8,4] -> [5,1,6,2,7,3,8,4]
搞定。
其次對2n!=3^k - 1的情況下,找一個最大的m,m滿足2m=3^k - 1並且m 比如假設n=6,那麼m=4.
假設一個素列A=[1,2,3,4,5,6,7,8,9,10,11,12]
首先A[m+1,...,n+m]做一個距離為m的右迴圈。
也就是[5,6,7,8,9,10]做一個距離為m的右迴圈,變成[7,8,9,10,5,6]
做完這個迴圈,[1,2,3,4,5,6,7,8,9,10,11,12]->[1,2,3,4,7,8,9,10,5, 6, 11,12]
然後對前2m項,做1的操作,[1,2,3,4,7,8,9,10,5, 6, 11,12]->[7,1,8,2,9,3,10,4,5, 6, 11,12]遞迴操作。
水木連結:
http://www.newsmth.net/bbscon.php?bid=1032&id=47005
論文連結:
http://vdisk.weibo.com/s/yXlrslXU0qvF-
【分析完畢】
本文來自微信:待字閨中,2013-08-05釋出,原創@陳利人 ,歡迎大家繼續關注微信公眾賬號“待字閨中”。
相關文章
- 巧妙變換;及可憐的小老鼠分析
- 相差最大;及逆序分析
- 巧妙排序;及相伴一生分析排序
- 找陣列的波谷;及巧妙排序的分析陣列排序
- 巧妙運用clip-path,實現CSS形狀變換CSS
- 灰度變換函式:對數及對比度拉伸變換函式
- 巧妙更換網路登入密碼密碼
- 傅立葉變換頻域時域分析
- 巧妙轉換ORACLE資料庫字符集Oracle資料庫
- 傅立葉變換和拉普拉斯變換的物理解釋及區別
- 【Python】python 基礎語法之列表、n維陣列的變換(取反(逆序)\切片等)Python陣列
- 非隔離DCDC變換器的CCM分析
- OpenGL模型檢視變換、投影變換、視口變換模型
- 逆序排列
- java日期時間各種變換及處理Java
- Windows變慢原因分析及解決方法(轉)Windows
- 無需進入XP安全模式 巧妙替換檔案(轉)模式
- RxJava 原始碼分析系列(四) -操作符變換原理RxJava原始碼
- Hough變換
- 傅立葉變換
- 霍夫變換圓檢測原理及 OpenCV API 應用OpenCVAPI
- 仿射變換及其變換矩陣的理解矩陣
- 小波變換與傅立葉變換的區別
- 【DWT筆記】傅立葉變換與小波變換筆記
- OpenGL中的座標變換、矩陣變換矩陣
- 逆序輸出字元字元
- JavaScript字串逆序排列JavaScript字串
- 連結串列逆序
- 陣列元素逆序陣列
- 巧妙的CSSCSS
- 離散傅立葉變換(DFT)和快速傅立葉變換(FFT)FFT
- 快速傅立葉變換原理介紹及遞迴程式碼實現遞迴
- OpenCV計算機視覺學習(3)——影像灰度線性變換與非線性變換(對數變換,伽馬變換)OpenCV計算機視覺
- 資料庫變慢了的分析及解決辦法資料庫
- RxSwift -- 變換Swift
- 快速傅立葉變換
- 巧妙改變某型別檔案的預設開啟方式(轉)型別
- 【OpenCV】影像變換(四-2)霍夫變換圓檢測OpenCV