LeetCode[526]Beautiful Arrangement(Java)

本文介绍了一种使用回溯法寻找所有由1到N整数组成的美丽排列的方法。美丽排列是指数组中每个位置的数要么能被其位置整除,要么其位置能被该数整除。文章提供了一个具体的例子,并给出了实现这一算法的Java代码。

Description:

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:

  1. The number at the ith position is divisible by i.
  2. i is divisible by the number at the ith 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:

  1. N is a positive integer and will not exceed 15.
Solution:
Backtracing(回溯法)
回溯法是暴力求解的优化,在遍历所有情况的过程中,一旦出现不符合要求的情况,则将该次遍历终止。将不能的解尽早舍弃。
设置一个递归函数,函数的参数携带当前解的信息,根据这些参数判断当前情况是可能解(记录或打印结果)或者不能解(回溯)。
Pick a starting point.
while(Problem is not solved)
	For each path from the starting point.
		check if selected path is safe, if yes select it
                and make recursive call to rest of the problem
		If recursive calls returns true, then return true.
		else undo the current move and return false.
	End For
	If none of the move works out, return false, NO SOLUTON.
Pick a starting point.
search(params)
	For each path from the starting point.
		check if selected path is safe, if yes select it
                and make recursive call to rest of the problem(search(new params))
		If recursive calls returns true, then return true.
		else undo the current move and return false.
	End For
	If none of the move works out, return false, NO SOLUTON.
class Solution {
    int result = 0;
    public int countArrangement(int N) {
        boolean[] visited = new boolean[N + 1];
        count(N, 1, visited);
        return result;
    }
    public void count(int N, int current, boolean[] visited){
        if(current > N){
            result++;
            return;
        }
        for(int i = 1; i <= N; i++){
            if(!visited[i] && (current % i == 0 || i % current == 0)){
                visited[i] = true;
                count(N, current + 1, visited);
                visited[i] = false;
            }
        }
    }
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值