LeetCode 526. Beautiful Arrangement
本题给定一个N,求1~N这N个数字一共有多少种排列方式,满足对第i位上的数字x,有x能被i整除,或i能被x整除。
本题可以用dfs解决,首先从N开始,如果满足题设条件则有一条边从一个数字通向下一个数字,如果不满足则没有,如果搜索到最后,即这N个数字都被访问过则count++,注意搜索过一种情况后要将visited数字恢复原样,不影响下一个情况的搜索。具体代码如下。
#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;
class Solution {
int count;
int N;
vector<bool> visited;
void dfs(const int index) {
if (index == 1) {
count++;
} else {
for (int i = 1; i <= N; ++i) {
if (!visited[i] && (i % index == 0 || index % i == 0) ) {
visited[i] = true;
dfs(index - 1);
visited[i] = false;
}
}
}
}
public:
int countArrangement(int N) {
count = 0;
this->N = N;
visited.assign(N + 1, false);
dfs(N);
return count;
}
};
int main(int argc, char const *argv[]) {
Solution s;
int N = 4;
cout << s.countArrangement(N) << endl;
system("pause");
return 0;
}
LeetCode 357. Count Numbers with Unique Digits
本题给出一个非负整数n,题目要求找出所有由不重复的数字构成的数x,满足0 ≤ x < 10^n。
这一题应该有数学方式可以解决,由于上一道题的启发,我还是想使用深搜暴力得出结果,思路也很类似,本题的节点只有10个,存在边的条件就是这个数字之前没有用到过。但是有一点需要特别注意,数字0是个特殊的情况,如果一个数字以几个0开头,那么这几个0应该被去掉,也就是说0并没有被用过,为了解决这种情况,我引入了一个int visited_n,记录一共访问了多少个数字,如果visited_n==0,那么任何一个数字都没有被访问,此时如果访问0,则不认为真正访问过0,不做记录,否则,如果visited_n不是0,那么一定有数字在0之前被访问,那就要记录0已经被访问过,之后的搜索中0就不会再出现了。
这种方法比较好想好理解,但是速度很慢,这次碰巧过了,如果本题的用例更多一些,则说不定就过不了了,不过反过来说,本题的情况其实很少,因为可用的数字只有10个,如果n==11则一定有重复的数字,所以11以上的情况和10一样,如果真的卡时间,也可以将1到10的结果都在本地求出来保存到数组里,交到oj里只需要包括查询的过程,相关代码在注释里(c语言)。
#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;
class Solution {
int count;
vector<bool> visited;
int visited_n;
void dfs(const int n) {
if (n == 0) {
count++;
} else {
for (int i = 0; i < 10; ++i) {
if (!visited[i]) {
if (i == 0 && visited_n == 0) {
dfs(n - 1);
} else {
visited[i] = true;
visited_n++;
dfs(n - 1);
visited[i] = false;
visited_n--;
}
}
}
}
}
public:
int countNumbersWithUniqueDigits(int n) {
count = 0;
visited.assign(10, false);
visited_n = 0;
dfs(n);
return count;
}
};
// int countNumbersWithUniqueDigits(int n) {
// const int result[] = { 1, 10, 91, 739, 5275, 32491, 168571, 712891, 2345851, 5611771, 8877691};
// if (n > 10)
// n = 10;
// return result[n];
// }
int main(int argc, char const *argv[]) {
Solution s;
int N = 0;
cout << s.countNumbersWithUniqueDigits(N) << endl;
system("pause");
return 0;
}