兩個經典遞迴問題:算瓶蓋與約瑟夫環
阿新 • • 發佈:2018-12-20
但凡遞迴,大部分都是兩句話能搞定的,先確定遞迴停止條件,向外翻轉,再確定迴圈條件,向內遞進
if(xx) return xx;
return def(xx...);
首先是算瓶蓋,一百元買啤酒,五元一瓶,三個換一瓶,兩個瓶身換一瓶,求最後總數:
首先,確定條件:
//規則
static int capRule=3,bottleRule=2;
然後是函式,為了方便大家一般都是取20作為條件的,(100/5)這個統一。
往後是形參有一點小不同,一種是總數=20,瓶蓋=0,瓶身=0,在函式裡再賦值瓶蓋跟瓶身
看到某華為面試題解方法參照如下:
int initCBDG(int drinks,int caps,int bottles){ caps%=capRule; bottles%=bottleRule; caps+=drinks; bottles+=drinks; if(caps<capRule&&bottles<bottleRule){ return drinks; } else{ return initCBDG(caps/capRule+bottles/bottleRule,caps,bottles)+drinks; } }
看上面那篇前,自己求了個解,既然總數是20,那其他兩個引數也是20了,所以:
int dg(int count,int caps,int bottles){ if (caps<capRule&&bottles<bottleRule) return count; return dg(caps/capRule+bottles/bottleRule,caps%capRule+caps/capRule+bottles/bottleRule,bottles%bottleRule+bottles/bottleRule+caps/capRule)+count; }
(遞迴只寫兩行的倔強)
兩個函式求的解是一樣的。
接下來是約瑟夫環,這個問題挺經典的,很多人都聽說過就不講了(沒聽過的戳這裡)
關於解,有很多,不同程式語言的,不同運算型別的,我找了一個最符合遞迴只寫兩行的解。
非常出色的一個解:
int ysfdg ( int sum, int value, int n) {
if ( n == 1 ) return ( sum + value - 1 ) %sum;
else return ( ysfdg ( sum-1, value,n-1 ) +value ) %sum;
}
原作者找不到了,但這個解真的很強,非常感謝。
第一個引數是總數,第二個引數指輪循次數,第三個引數就是你想要第幾個人出列他的下標是幾。
ps:有一點需要注意的是,這個解不是單純求最後一個出列人數,而是指定第幾個人出列,得出他的下標(記得+1)