Skip to content

Commit

Permalink
Update android-unlock-patterns.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
kamyu104 committed May 23, 2016
1 parent 84436ac commit 15903de
Showing 1 changed file with 75 additions and 4 deletions.
79 changes: 75 additions & 4 deletions C++/android-unlock-patterns.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,78 @@
// Time: O(n!)
// Space: O(n)
// Time: O(9 * 2^9)
// Space: O(9 * 2^9)

class Solution {
public:
int numberOfPatterns(int m, int n) {
// dp[i][j]: i is the set of the numbers in binary presentation,
// d[i][j] is the number of ways ending with the number j.
vector<vector<int>> dp(1 << 9 , vector<int>(9, 0));
for (int i = 0; i < 9; ++i) {
dp[merge(0, i)][i] = 1;
}

vector<int> keys(9, 0);
for (int i = 0; i < dp.size(); ++i) {
const auto count = number_of_key(i);
if (count > n) {
continue;
}
for (int j = 0; j < 9; ++j) {
if (!contain(i, j)) {
continue;
}
keys[count - 1] += dp[i][j];

const auto x1 = j / 3;
const auto y1 = j % 3;
for (int k = 0; k < 9; ++k) {
if (contain(i, k)) {
continue;
}
const auto x2 = k / 3;
const auto y2 = k % 3;
if (((x1 == x2 && abs(y1 - y2) == 2) ||
(y1 == y2 && abs(x1 - x2) == 2) ||
(abs(x1 - x2) == 2 && abs(y1 - y2) == 2)) &&
!(contain(i, convert((x1 + x2) / 2, (y1 + y2) / 2)))) {
continue;
}
dp[merge(i, k)][k] += dp[i][j];
}
}
}
int res = 0;
for (int i = m - 1; i < n; ++i) {
res += keys[i];
}
return res;
}

private:
inline int merge(int i, int j) {
return i | (1 << j);
}

inline int number_of_key(int i) {
int count = 0;
for (; i; i &= i - 1) {
++count;
}
return count;
}

inline bool contain(int i, int j) {
return i & (1 << j);
}

inline int convert(int i, int j) {
return 3 * i + j;
}
};

// Time: O(9!)
// Space: O(9)
class Solution2 {
public:
int numberOfPatterns(int m, int n) {
int count = 0;
Expand Down Expand Up @@ -55,11 +126,11 @@ class Solution {
visited[convert(i, j)] = false;
}

int convert(int i, int j) {
inline int convert(int i, int j) {
return 3 * i + j;
}

bool valid(int i, int j) {
inline bool valid(int i, int j) {
return i >= 0 && i < 3 && j >= 0 && j < 3;
}
};

0 comments on commit 15903de

Please sign in to comment.