1.输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
class Solution {
public:
vector<vector<int>> out;
vector<int> tmp;
vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
if(root!=nullptr)
dfs(root,expectNumber);
return out;
}
void dfs(TreeNode* root,int num)
{
if(root!=nullptr)
tmp.push_back(root->val);
if(num-root->val==0&&root->left==nullptr&&root->right==nullptr)
out.push_back(tmp);
if(root->left)
dfs(root->left,num-root->val);
if(root->right)
dfs(root->right,num-root->val);
tmp.pop_back();
}
};
2.输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
//先中序遍历,然后取出每个节点连接,注意特殊情况
class Solution {
public:
vector<TreeNode*> v;
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree==nullptr)
return nullptr;
MidTravel(pRootOfTree);
if(v.size()==1)
return v[0];
for(int i=0;i<v.size()-1;i++)
{
v[i]->right=v[i+1];
v[i+1]->left=v[i];
}
v[0]->left=nullptr;
v[v.size()-1]->right=nullptr;
return v[0];
}
void MidTravel(TreeNode* pRoot)
{
if(pRoot!=nullptr)
{
MidTravel(pRoot->left);
v.push_back(pRoot);
MidTravel(pRoot->right);
}
}
};
3.输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。(全排列问题,回溯法,二叉树,i代表输的深度,j代表同一层的节点数)
class Solution {
public:
vector<string> vs;
vector<string> Permutation(string str) {
if(str.size()>0)
{
PermutationHelp(str,0);
}
sort(vs.begin(),vs.end());
return vs;
}
void PermutationHelp(string str,int i)
{
if(i==str.size()-1)
{
if(!hasval(vs,str))
vs.push_back(str);
}
else
{
for(int j=i;j<str.size();j++)
{
swap(str[i],str[j]);
PermutationHelp(str,i+1);
swap(str[i],str[j]);
}
}
}
bool hasval(vector<string> v,string val)
{
vector<string>::iterator iter;
iter=find(v.begin(),v.end(),val);
if(iter==v.end())
return false;
else
return true;
}
};
4.数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。(秒过)
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.size()==0)
return 0;
sort(numbers.begin(),numbers.end());
int count=0;
int num=numbers[0];
for(int i=0;i<numbers.size();i++)
{
if(numbers[i]==num)
count++;
else
{
count=1;
num=numbers[i];
}
if(count>numbers.size()/2)
return num;
}
return 0;
}
};
5.输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。(秒解)
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> v;
if(k>input.size())
return v;
if(input.size()==0)
return v;
sort(input.begin(),input.end());
for(int i=0;i<k;i++)
{
v.push_back(input[i]);
}
return v;
}
};
6.给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)(子序列)
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
int sum=0;
int max=array[0];
for(int i=0;i<array.size();i++)
{
sum+=array[i];
if(sum<array[i]) //这里记下开始的位置
sum=array[i];
if(sum>max)
max=sum;
}
return max;
}
};
7.输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。(秒接,同回溯法,全排列问题)
class Solution {
public:
vector<long long> num;
string PrintMinNumber(vector<int> numbers) {
if(numbers.size()==0)
return "";
else
PrintMinNumberhelp(numbers,0);
long long min=num[0];
for(int i=0;i<num.size();i++)
{
min=num[i]<min?num[i]:min;
}
return to_string(min);
}
void PrintMinNumberhelp(vector<int> numbers,int i)
{
long long sum;
if(i==numbers.size()-1)
{
string s;
for(int i=0;i<numbers.size();i++)
s+=to_string(numbers[i]);
sum=stoll(s);
if(!hasval(num,sum))
num.push_back(sum);
}
else
{
for(int j=i;j<numbers.size();j++)
{
swap(numbers[i],numbers[j]);
PrintMinNumberhelp(numbers,i+1);
swap(numbers[i],numbers[j]);
}
}
}
bool hasval(vector<long long> v,long long val)
{
auto it=find(v.begin(),v.end(),val);
if(it==v.end())
return false;
else
return true;
}
};