知乎連接是:https://zhuanlan.zhihu.com/p/38850888程序員
題目信息:一副從1到n的牌,每次從牌堆頂取一張放桌子上,再取一張放牌堆底,直到手裏沒牌,最後桌子上的牌是從1到n有序,設計程序,輸入n,輸出牌堆的順序數組數組
發現題目比較有意思,小時候還真這麼玩過,當時也是一張一張的試出來,而後秀給小夥伴們看,拿到題目本身就琢磨的開始寫代碼spa
static void Main(string[] args) { int x = 10; int[] temp = new int[x]; for (int i = 0; i < x; i++) { temp[i] = i + 1; } temp = JustAgain(temp); Console.WriteLine(string.Join(" ", temp)); } static int[] JustAgain(int[] list) { while (true) { int CurrentInt = 0; int WantInt = 0; int CurrentIndex = 0; int WantIndex = 0; if (JustTest(list, 1, out CurrentInt, out WantInt) == false) { for (int i = 0; i < list.Length; i++) { if (list[i] == CurrentInt) { CurrentIndex = i; } else if (list[i] == WantInt) { WantIndex = i; } } list[WantIndex] = CurrentInt; list[CurrentIndex] = WantInt; return JustAgain(list); } return list; } } static bool JustTest(int[] list, int TempCurrentInt, out int CurrentInt, out int WantInt) { if (TempCurrentInt != 1 && list.Length > 1) { //將第一位數字換到最後一位 var tempInt = list[0]; for (int i = 0; i < list.Length - 1; i++) { list[i] = list[i + 1]; } list[list.Length - 1] = tempInt; } if (list[0] == TempCurrentInt) { if (list.Length == 1) { CurrentInt = 0; WantInt = 0; return true; } //移除第一位數字 int[] TempNew = new int[list.Length - 1]; for (int i = 0; i < TempNew.Length; i++) { TempNew[i] = list[i + 1]; } return JustTest(TempNew, ++TempCurrentInt, out CurrentInt, out WantInt); } else { CurrentInt = list[0]; WantInt = TempCurrentInt; return false; } }
寫的過程當中發現了點小問題,基礎知識不夠紮實,原本傳遞的是List,後來發現List是引用類型,子方法裏操做完,實際內存地址裏的List數據也跟的會變,無奈改爲了數組操做。寫這個花了2小時,功力仍是不夠。。。設計
原文中的微軟大佬說的暈頭轉向的,沒明白啥逆向解決code
「取一個1~n的數組,這裏爲了說明取n=5。按照題目中的規則變換,獲得數組:[1 3 5 4 2],將該數組下標與值互換獲得[1 5 2 4 3],即爲答案。解釋:[1 3 5 4 2]的意義是,通過變換,原數組中3號位置的數字如今2號槽,原數組中5號位置的數字如今3號槽...
如今已知變換後的槽存放的是1~n,故只需將下標與值互換便可獲得待求數組。
這道題還能夠繼續擴展:
1.變換規則更復雜使得沒法逆向模擬還原原數組;
2.最終獲得的序列能夠擴展爲任意序列。請你們之後不要黑微軟是養老院了」
可是樓主貌似沒理解全,問道你這些數字是數組的下標嗎
後面這位微軟的程序員也補充了一下,[]括起來的全部元素都是實際的數字(題目中牌上的數字)。下標從1開始
直到看到輪子哥的解釋blog
譬如說一共有5張牌,12345那麼玩一遍的結果是24531,可是桌子上的牌是12345,假設原牌數組是x,那麼顯然
x[2]=1
x[4]=2
x[5]=3
x[3]=4
x[1]=5
原來就是實際操做走一遍(因此是紙牌或者撲克),獲得了真實的模擬數據,再根據角標互換原理,便可得出真實的序列,這方法過高了,真的是解決這道題的實踐+理論完美組合,微軟不是敬老院,我服。內存