DP (3) -- Count Numbers with Unique Digits,Decode Ways,Unique Binary Search Trees I, II

来源:互联网 发布:粉底液 mac水漾 编辑:程序博客网 时间:2024/06/15 14:11

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.


1. 这道题类似爬台阶的思路。记录每一位的前两位和前一位的走法。需要注意的是处理0的问题。

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


0 0
原创粉丝点击