Count Numbers with Unique Digits
Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n.
Example:
Given n = 2, return 91. (The answer should be the total numbers in the range of 0 ≤ x < 100, excluding [11,22,33,44,55,66,77,88,99]
)
排列组合问题, n = 2时, 有 10+9*9种; n = 3时,有 10+9*9+9*9*8种。注意处理n < 2时的特殊情况。
int countNumbersWithUniqueDigits(int n) {
int rst = 0;
if(n < 2) return rst = (n == 1) ? 10 : 1;
int product = 9;
for(int i = 2; i < n + 1; i++){
product *= (11 - i);
rst += product;
}
return rst + 10;
}
Decode Ways
A message containing letters from A-Z
is being encoded to numbers using the following mapping:
'A' -> 1 'B' -> 2 ... 'Z' -> 26
Given an encoded message containing digits, determine the total number of ways to decode it.
For example,
Given encoded message "12"
, it could be decoded as "AB"
(1 2) or "L"
(12).
The number of ways decoding "12"
is 2.
2. 不使用stoi 而是使用自己编写的 isValid() 判断是否decode会减少很多代码量。
所有测试用例:"0","4116101516","41106101516","10","6003","101","110","100"
class Solution {
public:
bool isValid(char a, char b){
return a == '1'||(a == '2' && b <='6'); //a不能为0,且数字必须属于[1,26]
}
int numDecodings(string s) {
int one = 1, two = 1;
if(s.size() == 0 || s[0] == '0') return 0;
for(int i = 1; i < s.size(); i++){
int tmp = two;
two = one;
if(s[i] != '0') one = isValid(s[i-1], s[i]) ? tmp + one : one; //如果可以与前一位组成 < 26 且可以decode
else if(!isValid(s[i-1], s[i])) return 0; //如果该位为0且与前一位不能decode
else { //如果连续两位为0
one = tmp;
two = 0;
}
}
return one;
}
};
Unique Binary Search Trees
Given n, how many structurally unique BST's (binary search trees) that store values 1...n?
For example,
Given n = 3, there are a total of 5 unique BST's.
1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3
1. 记录树的结点数为n时可能树的个数。
2. 当n = i时所有的可能的情况为,数字i的子树的结点树分别为0,1,2...i-1. 当子树的结点树为0时,可能的情况为u[0] * u[i-1]; 结点树为2时,可能的情况为u[2] * u[i-1-2],依次类推。
3. 因为计算的过程中前后是重复的,所以可以只计算一半,然后根据奇偶确定是否加上中位数。
int numTrees(int n) {
int u[n];
u[0] = 1; u[1] = 1;
for(int i = 2; i < n + 1; i++){
int cur = 0;
for(int j = 0; j < i / 2; j++){
cur += u[j] * u[i-1-j];
}
cur *= 2;
if(i % 2 != 0) cur += pow(u[(i-1)/2], 2);
u[i] = cur;
}
return u[n];
}
Unique Binary Search Trees II
Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1...n.
跟之前不同在于这次要给出所有的树。
解法1:递归
1. 划定子树的左右边界,返回所有可能的子树。
2. 之前搞错的一点是将 TreeNode* root = new TreeNode(i); 放在了循环的外面。c++中的push_back的对象如果是指针的话,拷贝的是指针的值,即指向同一块内存区域。因此如果放在外面的话,指针指向的值改变,vector之前储存的值也会改变。对于Java 而言,由于list在添加元素时会复制一个新的对象,所以后续操作对list中的对象是没有影响的。
vector<TreeNode*> constructTrees(int leftBound, int rightBound){
vector<TreeNode*> rst;
if(leftBound > rightBound){ //此处返回NULL,后续无需判断子树数量是否为0
rst.push_back(NULL);
return rst;
}
for(int i = leftBound; i <= rightBound; i++){
vector<TreeNode*> leftTrees = constructTrees(leftBound, i-1);
vector<TreeNode*> rightTrees = constructTrees(i+1, rightBound);
for(int m = 0; m < leftTrees.size(); m++){
for(int n = 0; n < rightTrees.size(); n++){
TreeNode* root = new TreeNode(i);
root->left = leftTrees[m] ;
root->right = rightTrees[n];
rst.push_back(root);
}
}
}
return rst;
}
vector<TreeNode*> generateTrees(int n) {
if(n == 0) return vector<TreeNode*>();
return constructTrees(1, n);
}
解法2:DP
https://discuss.leetcode.com/topic/6711/share-a-c-dp-solution-with-o-1-space