leetcode刷題歸檔 -- 洗牌算法

洗牌算法

打亂一個沒有重複元素的數組。

示例:

// 以數字集合 1, 2 和 3 初始化數組。
int[] nums = {1,2,3};
Solution solution = new Solution(nums);

// 打亂數組 [1,2,3] 並返回結果。任何 [1,2,3]的排列返回的概率應該相同。
solution.shuffle();

// 重設數組到它的初始狀態[1,2,3]。
solution.reset();

// 隨機返回數組[1,2,3]打亂後的結果。
solution.shuffle();

來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/shuffle-an-array
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處

我的題解

最開始我的思路呢,是這樣

在這裏插入圖片描述
很快我就發現這樣不行。
有多快呢?寫完就發現了。

因爲vector的刪除需要迭代器,慢吞吞的爬過去,刪除,再爬到另一個位置,刪除,再爬···
慢死了。

後來學聰明瞭,換這套:
在這裏插入圖片描述

當然,每種情況出現概率如何,我覺得是相等的,如果有大神可以算一下,我準備去買那個程序員的數學課了,學完之後,老規矩,等我博客嘿嘿。

看代碼:

class Solution {
public:
    Solution(vector<int> nums): v(nums) {}
    
    /** Resets the array to its original configuration and return it. */
    vector<int> reset() {
        return v;
    }
    
    /** Returns a random shuffling of the array. */
    vector<int> shuffle() {
        vector<int> res = v;
        for (int i = 0; i < res.size(); ++i) {
            int t = i + rand() % (res.size() - i);
            swap(res[i], res[t]);
        }
        return res;
    }
    
private:
    vector<int> v;
};

官方題解

方法二: Fisher-Yates 洗牌算法 【通過】
思路

我們可以用一個簡單的技巧來降低之前算法的時間複雜度和空間複雜度,那就是讓數組中的元素互相交換,這樣就可以避免掉每次迭代中用於修改列表的時間了。

算法

Fisher-Yates 洗牌算法跟暴力算法很像。在每次迭代中,生成一個範圍在當前下標到數組末尾元素下標之間的隨機整數。接下來,將當前元素和隨機選出的下標所指的元素互相交換 - 這一步模擬了每次從 “帽子” 裏面摸一個元素的過程,其中選取下標範圍的依據在於每個被摸出的元素都不可能再被摸出來了。此外還有一個需要注意的細節,當前元素是可以和它本身互相交換的 - 否則生成最後的排列組合的概率就不對了。

作者:LeetCode
鏈接:https://leetcode-cn.com/problems/shuffle-an-array/solution/da-luan-shu-zu-by-leetcode/ 來源:力扣(LeetCode) 著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

class Solution {
    private int[] array;
    private int[] original;

    Random rand = new Random();

    private int randRange(int min, int max) {
        return rand.nextInt(max - min) + min;
    }

    private void swapAt(int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    public Solution(int[] nums) {
        array = nums;
        original = nums.clone();
    }
    
    public int[] reset() {
        array = original;
        original = original.clone();
        return original;
    }
    
    public int[] shuffle() {
        for (int i = 0; i < array.length; i++) {
            swapAt(i, randRange(i, array.length));
        }
        return array;
    }
}

> 作者:LeetCode
> 鏈接:https://leetcode-cn.com/problems/shuffle-an-array/solution/da-luan-shu-zu-by-leetcode/ 來源:力扣(LeetCode) 著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章