逛知乎,記一個算法的題目

知乎連接是: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

原來就是實際操做走一遍(因此是紙牌或者撲克),獲得了真實的模擬數據,再根據角標互換原理,便可得出真實的序列,這方法過高了,真的是解決這道題的實踐+理論完美組合,微軟不是敬老院,我服。內存

相關文章
相關標籤/搜索