数组的全排列
class Solution {
public:
vector<vector<int>> res;
/*
* @param nums: A list of integers.
* @return: A list of permutations.
*/
vector<vector<int>> permute(vector<int> &nums) {
// write your code here
vector<int> value;
proccess(nums,0);
return res;
}
void proccess(vector<int> &nums, int index){
if(index == nums.size()){
res.push_back(nums);
return;
}
for (int j = index; j < nums.size() ; j++) {
swap(nums[index], nums[j]);
proccess(nums, index+1);//point1
swap(nums[index], nums[j]);
}
}
};
题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排
列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
全排列在非常多程序都有应用,是一个非经常见的算法,常规的算法是一种递归的算法,这样的算法的得到基于下面的分析思路。 给定一个具有n个元素的集合(n>=1),要求输出这个集合中元素的全部可能的排列。
一、递归实现
比如,假设集合是{a,b,c},那么这个集合中元素的全部排列是{(a,b,c),(a,c,b),(b,a,c),(b,c,a),(c,a,b),(c,b,a)},显然,给定n个元素共同拥有n!种不同的排列,假设给定集合是{a,b,c,d},能够用以下给出的简单算法产生其全部排列,即集合(a,b,c,d)的全部排列有以下的排列组成:
(1)以a开头后面跟着(b,c,d)的排列
(2)以b开头后面跟着(a,c,d)的排列
(3)以c开头后面跟着(a,b,d)的排列
(4)以d开头后面跟着(a,b,c)的排列,这显然是一种递归的思路,于是我们得到了下面的实现:
class Solution {
public:
vector<string> Permutation(string str)
{
vector<string> array ;
if(!str.size()) return array;
Permutation(array,str,0);
return array;
}
void Permutation(vector<string> &array,string str,int begin){
if(begin==str.size())
array.push_back(str);
for(int i =begin; i< str.size();i++){
swap(str[i],str[begin]);
Permutation(array,str,begin+1);
swap(str[i],str[begin]);
}
}
};
有时候递归的效率使得我们不得不考虑除此之外的其它实现,非常多把递归算法转换到非递归形式的算法是比較难的,这个时候我们不要忘记了标准模板库已经实现的那些算法,这让我们非常轻松。STL有一个函数next_permutation(),它的作用是假设对于一个序列,存在依照字典排序后这个排列的下一个排列,那么就返回true且产生这个排列,否则返回false。注意,为了产生全排列,这个序列要是有序的,也就是说要调用一次sort。实现非常easy,我们看一下代码
class Solution {
public:
vector<string> Permutation(string str) {
vector<string> array;
if(str.size() == 0) return array;
do{
array.push_back(str);
}
while ( next_permutation(str.begin(),str.end()) );
return array;
}
第一次只出现一次的字符
class Solution {
public:
/**
* @param str: str: the given string
* @return: char: the first unique character in a given string
*/
unordered_map<char,int> help;
char firstUniqChar(string &str) {
// Write your code here
for (int i = 0; i < str.size(); i++) {
help[str[i]] = help[str[i]] + 1;
}
for (int i = 0; i < str.size(); i++) {
if(help[str[i]] == 1) return str[i];
}
return ' ';
}
};
245. 子树
有两个不同大小的二叉树: T1 有上百万的节点; T2 有好几百的节点。请设计一种算法,判定 T2 是否为 T1的子树。
样例
样例 1:
输入:{1,2,3,#,#,4},{3,4}
输出:true
解释:
下面的例子中 T2 是 T1 的子树:
1 3
/ \ /
T1 = 2 3 T2 = 4
/
4
样例 2:
输入:{1,2,3,#,#,4},{3,#,4}
输出:false
解释:
下面的例子中 T2 不是 T1 的子树:
1 3
/ \ \
T1 = 2 3 T2 = 4
/
4
注意事项
若 T1 中存在从节点 n 开始的子树与 T2 相同,我们称 T2 是 T1 的子树。也就是说,如果在 T1 节点 n
处将树砍断,砍断的部分将与 T2 完全相同。
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param T1: The roots of binary tree T1.
* @param T2: The roots of binary tree T2.
* @return: True if T2 is a subtree of T1, or false.
*/
bool isSubtree(TreeNode * T1, TreeNode * T2) {
// write your code here
if(!T2) return true;
if(!T1) return false;
return proccess(T1,T2)||isSubtree(T1->left,T2)||isSubtree(T1->right,T2);
}
bool proccess(TreeNode *t1, TreeNode*t2){
if(!t1 && !t2) return true;
if((t1 && !t2) || (!t1 && t2)) return false;
if(t1->val == t2->val)
return proccess(t1->left, t2->left) && proccess(t1->right,t2->right);
return false;
}
};
二叉树的堆成性
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param root: root of the given tree
* @return: whether it is a mirror of itself
*/
bool isSymmetric(TreeNode * root) {
// Write your code here
if(!root) return true;
return proccess(root->left,root->right);
}
bool proccess(TreeNode *rootLeft, TreeNode *rootRight){
if(!rootLeft && !rootRight) return true;
if(rootLeft && rootRight && (rootLeft->val == rootRight->val))
return proccess(rootLeft->left,rootRight->right) && proccess(rootLeft->right,rootRight->left);
return false;
}
};