相差最大;及逆序分析
今日面試題:相差最大
給定無序陣列A,線上性時間內找到i和j,j>i,並且保證A[j]-A[i]是最大的。
======================================
逆序分析
原題
一個整數,可以表示為二進位制的形式,請給出儘可能多的方法對二進位制進行逆序操作。 例如:10000110 11011000的逆序為 00011011 01100001
分析
題目中說是一個整數,對它的二進位制進行逆序。並不是一個01字串,或者01的陣列。那麼我們該如何解決這個問題呢?方法還是比較多的,有的中規中矩、有的非常巧妙。我們要掌握中規中規的方法,見識更多的巧妙的方法。慢慢的,能夠舉一反三,在遇到新的問題時,能夠有靈思妙想。
最直接的方法
直接的方法,很容易想到:有如下程式碼: int v = 111;
int r = v;
int s = 32;
for (; 0 != v; v >>= 1) {
r <<= 1;
r |= v & 1;
s--;
}
r <<= s;
System.out.println(r);
程式碼比較好理解,取到v的最低位,作為r的最高位;v每取一次最低位,則右移一位;r每確定一位,則左移一位。同時記錄移動了多少位,最終要補齊。
通過查表的方法
在遇到位操作的問題時,往往題目中限定了總的位數,比如這個題目,我們可以認為32位。這就給我們帶來了一個以空間換時間的解決思路:查表法。位數是固定的,可以申請空間,儲存預先計算好的結果,在計算其他的結果的時候,則查表即可。
32位相對於查表來講,還是太大了。既然這樣縮小範圍,32個bit,也就是4個byte。每個byte 8bit,可以表示0-255的整數。可以通過申請256大小的陣列,儲存這256個整數,二進位制逆序之後的整數。然後將一個32位的整數,劃分為4個byte,每一個byte查表得到逆序的整數:r1,r2,r3,r4。按照r4r3r2r1順序拼接二進位制得到的結果就是最終的答案。
這是一個思路,大家可以進一步思考,嘗試。
巧妙的方法
我們這裡主要分析這個巧妙的方法,核心思想是:分治法。即:
- 逆序32位分解為兩個逆序16位的
- 逆序16位分解為兩個逆序8位的
- 逆序8位分解為兩個逆序4位的
- 逆序4位分解為兩個逆序2位的
最後一個2位的逆序,直接交換即可。也就是分治遞迴的終止條件。但是,在上面的過程中,還沒有應用到位操作的技巧。根據動態規劃的思想,我們可以自底向上的解決這個問題:
- 每2位為一組,進行交換,完成2位逆序
- 每4位為一組,前面2位與後面2位交換,完成4位逆序
- 每8位為一組,前面4位和後面4為交換,完成8位的逆序
- 每16位為一組,前面8位和後面8位交換,完成16位的逆序
2組16位的交換,完成32位的逆序
通過下面的例子,詳解上面的過程,我們以16位為例:10000110 11011000
1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 |
0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 |
0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 |
0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |
經過4步,逆序完成。推而廣之,總的時間複雜度為O(logn),n是二進位制的位數。這個方法可以推廣到任意位。
示例程式碼如下:
int v = 111;
v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
v = ( v >> 16 ) | ( v << 16);
System.out.println(v);
上面的思路理解了,程式碼不難理解。例如第二行,前邊是取偶數位,後面是取奇數位,奇數位左移一位,偶數位右移一位,再取或,就是交換了奇數偶數位。也就是第一個步驟。
基於位運算的一些巧妙的方法有很多。大家可以自行研究,後面會和大家分享更多的面試題目。
【分析完畢】
本文來自微信:待字閨中,2013-08-06釋出,原創@陳利人 ,歡迎大家繼續關注微信公眾賬號“待字閨中”。
相關文章
- 逆序排列
- 逆序數
- 逆序輸出字元字元
- JavaScript字串逆序排列JavaScript字串
- 連結串列逆序
- 陣列元素逆序陣列
- 查詢排序二叉樹的最小值,最大值,Next指標,並逆序列印排序二叉樹指標
- P1908 逆序對
- 逆序對的數量
- 【SSLOJ 3347】動態逆序對
- G - 逆序對的數量
- 陣列中的逆序對陣列
- 逆序的三位數
- 逆序對《演算法很美》演算法
- 樹狀陣列和逆序對陣列
- [CQOI2011] 動態逆序對
- 逆序對的數量 - 題解
- 788. 逆序對的數量
- rust-algorithms:16-字元逆序RustGo字元
- 求逆序對(介紹+題目)
- JavaScript 計算兩個時間相差天數JavaScript
- 時間相差秒數_Golang 時間操作大全Golang
- HDU 2689 【歸併排序求逆序對】排序
- abc284F 字首+逆序+字尾
- AcWing 788. 逆序對的數量
- 兄弟們寫了個取當前出現未達到佔比且相差最大的型別的演算法,但感覺不是很好型別演算法
- 演算法之逆序對兒查詢演算法
- 逆序對的數量(歸併排序模板)排序
- python對指定字串逆序的6種方法Python字串
- JZ-035-陣列中的逆序對陣列
- 歸併排序的經典-求逆序對排序
- 求逆序對的各種演算法演算法
- OGG for kafka op_ts 和current_ts相差較大Kafka
- php 計算兩個日期之間相差多少天PHP
- 為什麼我總和效能指標相差很遠?指標
- Unsortbin attack原理及分析
- MYSQL 對錶最大ID 搶加鎖時的阻塞分析MySql
- 收益最大化定價策略分析_PSM模型運用模型
- 劍指Offer-37-陣列中逆序對陣列