1. 程式人生 > >526. Beautiful Arrangement(python+cpp)

526. Beautiful Arrangement(python+cpp)

題目:

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 i

th position.
Now given N, how many beautiful arrangements can you construct?
Example 1:

Input: 2 
Output: 2 
Explanation: 
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.

解釋:
1.arr[i]能夠被i整除,i = 1, 2, …, N2.i能夠被arr[i]整除,i = 1, 2, …, N
2.pos%i==0 or i%pos==0 ,pos表示當前的位置,i表示當前可用的數字
簡單分析該題可以發現,將N個數字放置在N個位置上,這樣的問題是較為典型的回溯問題:假設前i個數字已經放置好(滿足條件1或條件2),則對於第i+1個位置,如果能從還未被放置的數字集合unused(或visited)中找到一個滿足條件的數字k,則將其放在第i+1個位置

,同時將k從unused中去掉(或者將visited[k - 1]標記為true),繼續對第i+2執行相同的操作(通過遞迴呼叫);如果找不到滿足條件的數字,則回溯到上一層,修改第i個位置的數字,再嘗試第i+1個位置···依此類推。
遞迴的base case應當是遞迴樹的高度達到了N,如果當前層次為第N層,則表示從0到N-1層得到的這條路徑是一個Beautiful Arrangement,count++。
python程式碼:

class Solution(object):
    def countArrangement(self, N):
        """
        :type N: int
        :rtype: int
        """
        self.visited=[False]*N
        self.count=0
        self.N=N
        def dfs(pos):
            if pos==0:
                self.count+=1
                return
            for i in xrange(1,self.N+1):
                #如果當前數字已經被使用或者兩個條件都不滿足
                if(self.visited[i-1] or (pos%i!=0 and i%pos!=0)):
                    continue
                #當前數字可以使用
                #深入
                self.visited[i-1]=True
                dfs(pos-1)
                #回溯
                self.visited[i-1]=False
        dfs(N)
        return self.count

c++程式碼:

class Solution {
public:
    int count=0;
    int global_N;
    vector<bool> visited;
    int countArrangement(int N) {
        global_N=N;
        visited=vector<bool>(N,false);
        dfs(N);
        return count;
    }
    void dfs(int pos)
    {
        if (pos==0)
            count++;
        for(int i=1;i<=global_N;i++)
        {
            if(visited[i-1] ||(i%pos!=0 && pos%i!=0) )
                continue;
            else 
            {
                visited[i-1]=true;
                dfs(pos-1);
                visited[i-1]=false;
            }
        }
    }
};

總結: