Trilogy公司的笔试题:根据指定规则用最少的步骤将数转为1
如果n為偶數,則將它除以2,如果n為奇數,則將它加1或者減1。問對于一個給定的n,怎樣才能用最少的步驟將它變到1。
??? 例如:n=11: ① ++n -> 12 ② n/2 -> 6 ③ n/2 -> 3?? ④ --n -> 2? ⑤ n/2 -> 1? 共需5步。
?
?
最簡單的方法就是用DP。設f(n)為所用的最少步驟。根據定義可得:
若n為偶數, f(n)=f(n/2) + 1;
若n為奇數, f(n)= min(f(n-1), f(n+1)) +1
???????????????? ??????= min(f((n-1)/2), f((n+1)/2)) +2
或者:
?f(2*k)=f(k)+1?
f(2*k+1)=min(f(k),f(k+1))+2
?
利用上述遞推公式,可以直接從數字1開始算到n,用一個數組保存前 n/2+1個數所用的最少步驟,但這時間和空間復雜度均為O(n),其實利用上面的遞推公式,可以實現時間復雜度為0(lg n)。觀察上面的遞推公式,可以發現,要計算n,只要計算n/2和n/2+1,如要計算59,只要計算:
59 -> 29,30 -> 14,15 -> 7,8 -> 3,4 -> 1,2。
?
代碼如下:
{
??unsigned?tmp=n,?flag=1,?ret=0,?next=1;
??while?(tmp>>=1)?flag<<=1;
??while?(flag>>=1)?{
????if?(n?&?flag)?{
??????if?(ret?>?next)?ret?=?next;
??????ret?+=?2;
??????++next;
????}?else?{
??????if?(next?>?ret)?next?=?ret;
??????next?+=?2;
??????++ret;
????}
??}
??return?ret;
}
上面的O(lg n)解法,對n先處理高位的0和1,下面的O(lg n)解法則恰恰相反,先處理n的低位的0和1。
將n(n>1)轉為二進制數表示
(下面的“加1”、“減1”操作均特指對奇數采取的操作,操作次數包括對偶數的操作次數。)
⑴ 如果n僅由m個連續的1組成(即n=2^m-1, m>=2),
① “加1”操作:?需要 m+1 次操作
② “減1”操作:?需要 2*(m-1) 次操作
?????? 顯然,僅當m=2(即n=3)時,“減1”所用的操作次數才比“加1”少。
⑵ 如果n可以表示為:x10m1k (m>=1, k>=1)
(x可以為空串或任意01序列,0m表示連續m個0,1k表示連續k個1)
??① “加1”操作:?k+1 次操作后得到x10m-11如果,接著用“減1”操作(注意,這不這一定最優解法),總共k+3次操作可得x10m-1。
??②“減1”操作:?2*k+1次操作后得到x10m-1
??顯然,僅當k=1時,“減1”所用的操作次數才可能比“加1”少。
?? 可以證明,對x10m1,“減1”所用的操作次數一定不會比“加1”的多。
?? (當k=1時,對x10m1,假設先進行一次“加1”操作最終所用的步驟數較少。“加1”操作后,在將x10m1轉為x11前,若用到“減1”操作,則可以直接對x10m1進行 “減1”操作,所有步驟更少,因而后面都是采用“加1”操作。
??? ?對x10m1(可表示為y01t0m1,y允許是空串),
“加1”操作?? 2*m+t+2 次后得到 ?y1
“減1”操作??????m+2 次后得到?y01t
(再用“加1操作”,m+t+3后也可得到y1)
由于對m>=1,恒有m+t+3 <= 2*m+t+2,因而對x10m1
“減1”操作能保證得到最優解。)
⑶ 總之,僅當n=3或n二進制表示的最低2位是01時,才用“減1”操作
代碼:
int?num2one(unsigned?n){
??if?(n==0)?return?-1;
??int?count=0;
??while?(1)?{
????while?((n&1)==0)?{?n?>>=?1u;?++count;?}
????if?(n<=3)?{
??????//?n只能為1或3,n為3時,還要進行兩步操作
??????count?+=?n?-?1;
??????break;
????}
????if?((n&3)==1)??--n;
????else?++n;
????++count;
??}
??return?count;
}
?
轉載于:https://www.cnblogs.com/flyinghearts/archive/2011/01/01/1923590.html
總結
以上是生活随笔為你收集整理的Trilogy公司的笔试题:根据指定规则用最少的步骤将数转为1的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ext
- 下一篇: .NET中如何通过文本框中按回车键进行的