[LeetCode] 526. Beautiful Arrangement

来源:互联网 发布:socket网络通信 编辑:程序博客网 时间:2024/06/06 13:31

Suppose you have N integers from 1 to N. We define a beautiful arrangement as an array that is constructed by these N numbers successfully if one of the following is true for the ith position (1 ? i ? N) in this array:

The number at the ith position is divisible by i.
i is divisible by the number at the ith position.
Now given N, how many beautiful arrangements can you construct?

Example 1:

Input: 2Output: 2Explanation: The first beautiful arrangement is [1, 2]:Number at the 1st position (i=1) is 1, and 1 is divisible by i (i=1).Number at the 2nd position (i=2) is 2, and 2 is divisible by i (i=2).The second beautiful arrangement is [2, 1]:Number at the 1st position (i=1) is 2, and 2 is divisible by i (i=1).Number at the 2nd position (i=2) is 1, and i (i=2) is divisible by 1.

Note:
N is a positive integer and will not exceed 15.

保证性能的关键,在于从后往前(i递减)

// 16ms, beats 71%class Solution {public:    int countArrangement(int N) {        vector<unordered_set<int>> candi(N + 1);        vector<bool> IsUsed(N + 1, false);        int cnt = 0;        for (int i = 1; i <= N; i++) {            for (int zoomup = 1; zoomup * i <= N; zoomup++) {                int prod = zoomup * i;                candi[i].insert(prod);                candi[prod].insert(i);            }        }        countArrangement(candi, IsUsed, N, cnt);        return cnt;    }private:    void countArrangement(vector<unordered_set<int>>& candi,                          vector<bool> &IsUsed, int nth, int &cnt) {        if (nth <= 0) {            cnt++;            return;        }        for (auto opt : candi[nth]) {            if (IsUsed[opt] == false) {                IsUsed[opt] = true;                countArrangement(candi, IsUsed, nth - 1, N, cnt);                IsUsed[opt] = false;            }        }    }};
// 6ms, beats 81%class Solution {public:    int countArrangement(int N) {        vector<int> num;        int cnt = 0;        for(int i = 0; i <= N; ++i)            num.push_back(i);        countArrangement(num, N, cnt);        return cnt;    }    void countArrangement(vector<int>& num, int n, int& cnt){        if (n <= 0) cnt++;        for(int i = 1; i <= n; ++i){            if(n % num[i] == 0 || num[i] % n ==0){                swap(num[i], num[n]);                countArrangement(num, n - 1, cnt);                swap(num[i], num[n]);            }        }    }};